Copy disabled (too large)
Download .txt
Showing preview only (45,205K chars total). Download the full file to get everything.
Repository: chernyadev/bigym
Branch: master
Commit: d98124454dfa
Files: 579
Total size: 75.1 MB
Directory structure:
gitextract_6orlelw8/
├── .github/
│ └── workflows/
│ └── build.yaml
├── .gitignore
├── .pre-commit-config.yaml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bigym/
│ ├── __init__.py
│ ├── action_modes.py
│ ├── bigym_env.py
│ ├── bigym_renderer.py
│ ├── const.py
│ ├── envs/
│ │ ├── __init__.py
│ │ ├── cupboards.py
│ │ ├── dishwasher.py
│ │ ├── dishwasher_cups.py
│ │ ├── dishwasher_cutlery.py
│ │ ├── dishwasher_plates.py
│ │ ├── groceries.py
│ │ ├── manipulation.py
│ │ ├── move_plates.py
│ │ ├── pick_and_place.py
│ │ ├── presets/
│ │ │ ├── cabinet.yaml
│ │ │ ├── cabinet_door.yaml
│ │ │ ├── cabinet_hob.yaml
│ │ │ ├── counter_base_2.yaml
│ │ │ ├── counter_base_2_hob.yaml
│ │ │ ├── counter_base_wall_1x1.yaml
│ │ │ ├── counter_base_wall_2x2.yaml
│ │ │ ├── counter_base_wall_3x1.yaml
│ │ │ ├── counter_dishwasher.yaml
│ │ │ ├── counter_dishwasher_cutlery_cabinet.yaml
│ │ │ ├── counter_dishwasher_wall_cabinet.yaml
│ │ │ ├── dishwasher.yaml
│ │ │ ├── move_plates.yaml
│ │ │ └── stack_blocks.yaml
│ │ ├── props/
│ │ │ ├── __init__.py
│ │ │ ├── cabintets.py
│ │ │ ├── cutlery.py
│ │ │ ├── dishwasher.py
│ │ │ ├── holders.py
│ │ │ ├── items.py
│ │ │ ├── kitchenware.py
│ │ │ ├── preset.py
│ │ │ ├── prop.py
│ │ │ └── tables.py
│ │ ├── reach_target.py
│ │ └── xmls/
│ │ ├── 3D_MODELS_ATTRIBUTION.md
│ │ ├── google_robot/
│ │ │ ├── assets/
│ │ │ │ ├── link_base_0_00.stl
│ │ │ │ ├── link_base_0_01.stl
│ │ │ │ ├── link_base_1_00.stl
│ │ │ │ ├── link_base_1_01.stl
│ │ │ │ ├── link_base_1_02.stl
│ │ │ │ ├── link_base_1_03.stl
│ │ │ │ ├── link_base_1_04.stl
│ │ │ │ ├── link_base_1_05.stl
│ │ │ │ ├── link_base_1_06.stl
│ │ │ │ ├── link_base_1_07.stl
│ │ │ │ ├── link_base_1_08.stl
│ │ │ │ ├── link_base_1_09.stl
│ │ │ │ ├── link_base_1_10.stl
│ │ │ │ ├── link_base_1_11.stl
│ │ │ │ ├── link_base_1_12.stl
│ │ │ │ ├── link_base_1_13.stl
│ │ │ │ ├── link_base_1_14.stl
│ │ │ │ ├── link_base_1_15.stl
│ │ │ │ ├── link_base_1_16.stl
│ │ │ │ ├── link_base_1_17.stl
│ │ │ │ ├── link_base_1_18.stl
│ │ │ │ ├── link_base_1_19.stl
│ │ │ │ ├── link_base_v.obj
│ │ │ │ ├── link_bicep.stl
│ │ │ │ ├── link_bicep_v.obj
│ │ │ │ ├── link_elbow.stl
│ │ │ │ ├── link_elbow_v.obj
│ │ │ │ ├── link_finger_base.stl
│ │ │ │ ├── link_finger_base_v.obj
│ │ │ │ ├── link_finger_tip.stl
│ │ │ │ ├── link_finger_tip_v.obj
│ │ │ │ ├── link_forearm.stl
│ │ │ │ ├── link_forearm_v.obj
│ │ │ │ ├── link_gripper.stl
│ │ │ │ ├── link_gripper_v.obj
│ │ │ │ ├── link_head_pan.stl
│ │ │ │ ├── link_head_pan_v.obj
│ │ │ │ ├── link_head_tilt.stl
│ │ │ │ ├── link_head_tilt_v.obj
│ │ │ │ ├── link_shoulder.stl
│ │ │ │ ├── link_shoulder_v.obj
│ │ │ │ ├── link_torso_00.stl
│ │ │ │ ├── link_torso_01.stl
│ │ │ │ ├── link_torso_v.obj
│ │ │ │ ├── link_wheel_v.obj
│ │ │ │ ├── link_wrist.stl
│ │ │ │ └── link_wrist_v.obj
│ │ │ ├── robot.xml
│ │ │ └── scene.xml
│ │ ├── h1/
│ │ │ ├── assets/
│ │ │ │ ├── left_ankle_link.stl
│ │ │ │ ├── left_elbow_link.stl
│ │ │ │ ├── left_hip_pitch_link.stl
│ │ │ │ ├── left_hip_roll_link.stl
│ │ │ │ ├── left_hip_yaw_link.stl
│ │ │ │ ├── left_knee_link.stl
│ │ │ │ ├── left_shoulder_pitch_link.stl
│ │ │ │ ├── left_shoulder_roll_link.stl
│ │ │ │ ├── left_shoulder_yaw_link.stl
│ │ │ │ ├── logo_link.stl
│ │ │ │ ├── pelvis.stl
│ │ │ │ ├── right_ankle_link.stl
│ │ │ │ ├── right_elbow_link.stl
│ │ │ │ ├── right_hip_pitch_link.stl
│ │ │ │ ├── right_hip_roll_link.stl
│ │ │ │ ├── right_hip_yaw_link.stl
│ │ │ │ ├── right_knee_link.stl
│ │ │ │ ├── right_shoulder_pitch_link.stl
│ │ │ │ ├── right_shoulder_roll_link.stl
│ │ │ │ ├── right_shoulder_yaw_link.stl
│ │ │ │ └── torso_link.stl
│ │ │ ├── h1.xml
│ │ │ └── h1_floating_base.xml
│ │ ├── hello_robot_stretch/
│ │ │ ├── assets/
│ │ │ │ ├── base_link_0.obj
│ │ │ │ ├── base_link_1.obj
│ │ │ │ ├── base_link_2.obj
│ │ │ │ ├── base_link_3.obj
│ │ │ │ ├── base_link_4.obj
│ │ │ │ ├── base_link_5.obj
│ │ │ │ ├── base_link_6.obj
│ │ │ │ ├── base_link_7.obj
│ │ │ │ ├── base_link_8.obj
│ │ │ │ ├── base_link_casterless.stl
│ │ │ │ ├── laser.obj
│ │ │ │ ├── link_arm_l0_0.obj
│ │ │ │ ├── link_arm_l0_1.obj
│ │ │ │ ├── link_arm_l0_2.obj
│ │ │ │ ├── link_arm_l1_0.obj
│ │ │ │ ├── link_arm_l1_1.obj
│ │ │ │ ├── link_arm_l2_0.obj
│ │ │ │ ├── link_arm_l2_1.obj
│ │ │ │ ├── link_arm_l3_0.obj
│ │ │ │ ├── link_arm_l3_1.obj
│ │ │ │ ├── link_arm_l4_0.obj
│ │ │ │ ├── link_arm_l4_1.obj
│ │ │ │ ├── link_aruco_inner_wrist.obj
│ │ │ │ ├── link_aruco_left_base.obj
│ │ │ │ ├── link_aruco_right_base.obj
│ │ │ │ ├── link_aruco_shoulder.obj
│ │ │ │ ├── link_aruco_top_wrist.obj
│ │ │ │ ├── link_gripper_0.obj
│ │ │ │ ├── link_gripper_1.obj
│ │ │ │ ├── link_gripper_finger_left_0.obj
│ │ │ │ ├── link_gripper_finger_left_1.obj
│ │ │ │ ├── link_gripper_finger_right_0.obj
│ │ │ │ ├── link_gripper_finger_right_1.obj
│ │ │ │ ├── link_gripper_fingertip_left.stl
│ │ │ │ ├── link_gripper_fingertip_right.stl
│ │ │ │ ├── link_head_0.obj
│ │ │ │ ├── link_head_1.obj
│ │ │ │ ├── link_head_10.obj
│ │ │ │ ├── link_head_11.obj
│ │ │ │ ├── link_head_2.obj
│ │ │ │ ├── link_head_3.obj
│ │ │ │ ├── link_head_4.obj
│ │ │ │ ├── link_head_5.obj
│ │ │ │ ├── link_head_6.obj
│ │ │ │ ├── link_head_7.obj
│ │ │ │ ├── link_head_8.obj
│ │ │ │ ├── link_head_9.obj
│ │ │ │ ├── link_head_pan_0.obj
│ │ │ │ ├── link_head_pan_1.obj
│ │ │ │ ├── link_head_tilt_0.obj
│ │ │ │ ├── link_head_tilt_1.obj
│ │ │ │ ├── link_left_wheel_0.obj
│ │ │ │ ├── link_left_wheel_1.obj
│ │ │ │ ├── link_lift_0.obj
│ │ │ │ ├── link_lift_1.obj
│ │ │ │ ├── link_lift_2.obj
│ │ │ │ ├── link_lift_3.obj
│ │ │ │ ├── link_lift_4.obj
│ │ │ │ ├── link_lift_5.obj
│ │ │ │ ├── link_lift_6.obj
│ │ │ │ ├── link_lift_7.obj
│ │ │ │ ├── link_lift_8.obj
│ │ │ │ ├── link_lift_9.obj
│ │ │ │ ├── link_mast.obj
│ │ │ │ ├── link_right_wheel_0.obj
│ │ │ │ ├── link_right_wheel_1.obj
│ │ │ │ ├── link_wrist_yaw.obj
│ │ │ │ └── respeaker_base.obj
│ │ │ ├── scene.xml
│ │ │ └── stretch.xml
│ │ ├── props/
│ │ │ ├── board/
│ │ │ │ ├── assets/
│ │ │ │ │ └── board.obj
│ │ │ │ └── board.xml
│ │ │ ├── box/
│ │ │ │ ├── assets/
│ │ │ │ │ └── box.obj
│ │ │ │ └── box.xml
│ │ │ ├── cube/
│ │ │ │ └── cube.xml
│ │ │ ├── cutlery/
│ │ │ │ ├── fork/
│ │ │ │ │ ├── assets/
│ │ │ │ │ │ ├── fork.obj
│ │ │ │ │ │ ├── fork_collision_001.obj
│ │ │ │ │ │ └── fork_collision_002.obj
│ │ │ │ │ ├── fork.xml
│ │ │ │ │ └── fork_convex.xml
│ │ │ │ ├── knife/
│ │ │ │ │ ├── assets/
│ │ │ │ │ │ ├── knife.obj
│ │ │ │ │ │ ├── knife_collision_001.obj
│ │ │ │ │ │ └── knife_collision_002.obj
│ │ │ │ │ ├── knife.xml
│ │ │ │ │ └── knife_convex.xml
│ │ │ │ └── spoon/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── spoon.obj
│ │ │ │ │ ├── spoon_collision_001.obj
│ │ │ │ │ └── spoon_collision_002.obj
│ │ │ │ ├── spoon.xml
│ │ │ │ └── spoon_convex.xml
│ │ │ ├── cutlery_tray/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── cutlery_tray.obj
│ │ │ │ │ ├── cutlery_tray_collision_001.obj
│ │ │ │ │ ├── cutlery_tray_collision_002.obj
│ │ │ │ │ ├── cutlery_tray_collision_003.obj
│ │ │ │ │ ├── cutlery_tray_collision_004.obj
│ │ │ │ │ ├── cutlery_tray_collision_005.obj
│ │ │ │ │ ├── cutlery_tray_collision_006.obj
│ │ │ │ │ ├── cutlery_tray_collision_007.obj
│ │ │ │ │ ├── cutlery_tray_collision_008.obj
│ │ │ │ │ ├── cutlery_tray_collision_009.obj
│ │ │ │ │ ├── cutlery_tray_collision_010.obj
│ │ │ │ │ └── cutlery_tray_collision_011.obj
│ │ │ │ └── cutlery_tray.xml
│ │ │ ├── dish_drainer/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── rack.obj
│ │ │ │ │ ├── rack_collision_001.obj
│ │ │ │ │ ├── rack_collision_002.obj
│ │ │ │ │ ├── rack_collision_003.obj
│ │ │ │ │ ├── rack_collision_004.obj
│ │ │ │ │ ├── rack_collision_005.obj
│ │ │ │ │ ├── rack_collision_006.obj
│ │ │ │ │ ├── rack_collision_007.obj
│ │ │ │ │ ├── rack_collision_008.obj
│ │ │ │ │ ├── rack_collision_009.obj
│ │ │ │ │ ├── rack_collision_010.obj
│ │ │ │ │ ├── rack_collision_011.obj
│ │ │ │ │ ├── rack_collision_012.obj
│ │ │ │ │ ├── rack_collision_013.obj
│ │ │ │ │ ├── rack_collision_014.obj
│ │ │ │ │ ├── rack_collision_015.obj
│ │ │ │ │ ├── rack_collision_016.obj
│ │ │ │ │ ├── rack_collision_017.obj
│ │ │ │ │ └── rack_collision_018.obj
│ │ │ │ └── dish_drainer.xml
│ │ │ ├── dishwasher/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── collision/
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_001.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_002.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_003.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_004.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_005.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_006.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_007.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_008.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_009.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_010.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_011.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_012.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_013.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_014.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_015.obj
│ │ │ │ │ │ ├── collision_dish_washer_mid_sprinkle.obj
│ │ │ │ │ │ ├── collision_door_001.obj
│ │ │ │ │ │ ├── collision_door_003.obj
│ │ │ │ │ │ ├── collision_door_004.obj
│ │ │ │ │ │ ├── collision_door_006.obj
│ │ │ │ │ │ ├── collision_door_007.obj
│ │ │ │ │ │ ├── collision_door_008.obj
│ │ │ │ │ │ ├── collision_door_009.obj
│ │ │ │ │ │ ├── collision_holder_001.obj
│ │ │ │ │ │ ├── collision_holder_002.obj
│ │ │ │ │ │ ├── collision_holder_003.obj
│ │ │ │ │ │ ├── collision_holder_004.obj
│ │ │ │ │ │ ├── collision_holder_005.obj
│ │ │ │ │ │ ├── collision_holder_006.obj
│ │ │ │ │ │ ├── collision_holder_007.obj
│ │ │ │ │ │ ├── collision_holder_008.obj
│ │ │ │ │ │ ├── collision_holder_009.obj
│ │ │ │ │ │ ├── collision_holder_010.obj
│ │ │ │ │ │ ├── collision_holder_011.obj
│ │ │ │ │ │ ├── collision_holder_012.obj
│ │ │ │ │ │ ├── collision_holder_013.obj
│ │ │ │ │ │ ├── collision_holder_014.obj
│ │ │ │ │ │ ├── collision_tray_001.obj
│ │ │ │ │ │ ├── collision_tray_002.obj
│ │ │ │ │ │ ├── collision_tray_003.obj
│ │ │ │ │ │ ├── collision_tray_004.obj
│ │ │ │ │ │ ├── collision_tray_005.obj
│ │ │ │ │ │ ├── collision_tray_006.obj
│ │ │ │ │ │ ├── collision_tray_007.obj
│ │ │ │ │ │ ├── collision_tray_008.obj
│ │ │ │ │ │ ├── collision_tray_009.obj
│ │ │ │ │ │ ├── collision_tray_010.obj
│ │ │ │ │ │ ├── collision_tray_011.obj
│ │ │ │ │ │ ├── collision_tray_012.obj
│ │ │ │ │ │ ├── collision_tray_013.obj
│ │ │ │ │ │ ├── collision_tray_014.obj
│ │ │ │ │ │ ├── collision_tray_015.obj
│ │ │ │ │ │ ├── collision_tray_016.obj
│ │ │ │ │ │ ├── collision_tray_017.obj
│ │ │ │ │ │ ├── collision_tray_018.obj
│ │ │ │ │ │ ├── collision_tray_019.obj
│ │ │ │ │ │ ├── collision_tray_020.obj
│ │ │ │ │ │ ├── collision_tray_021.obj
│ │ │ │ │ │ ├── collision_tray_022.obj
│ │ │ │ │ │ ├── collision_tray_023.obj
│ │ │ │ │ │ ├── collision_tray_024.obj
│ │ │ │ │ │ ├── collision_tray_025.obj
│ │ │ │ │ │ ├── collision_tray_026.obj
│ │ │ │ │ │ ├── collision_tray_027.obj
│ │ │ │ │ │ ├── collision_tray_028.obj
│ │ │ │ │ │ ├── collision_tray_029.obj
│ │ │ │ │ │ ├── collision_tray_030.obj
│ │ │ │ │ │ ├── collision_tray_031.obj
│ │ │ │ │ │ ├── collision_tray_032.obj
│ │ │ │ │ │ ├── collision_tray_033.obj
│ │ │ │ │ │ ├── collision_tray_mid_001.obj
│ │ │ │ │ │ ├── collision_tray_mid_002.obj
│ │ │ │ │ │ ├── collision_tray_mid_003.obj
│ │ │ │ │ │ ├── collision_tray_mid_004.obj
│ │ │ │ │ │ ├── collision_tray_mid_005.obj
│ │ │ │ │ │ ├── collision_tray_mid_006.obj
│ │ │ │ │ │ ├── collision_tray_mid_007.obj
│ │ │ │ │ │ ├── collision_tray_mid_008.obj
│ │ │ │ │ │ ├── collision_tray_mid_009.obj
│ │ │ │ │ │ ├── collision_tray_mid_010.obj
│ │ │ │ │ │ ├── collision_tray_mid_011.obj
│ │ │ │ │ │ ├── collision_tray_mid_012.obj
│ │ │ │ │ │ ├── collision_tray_mid_013.obj
│ │ │ │ │ │ ├── collision_tray_mid_014.obj
│ │ │ │ │ │ ├── collision_tray_mid_015.obj
│ │ │ │ │ │ ├── collision_tray_mid_016.obj
│ │ │ │ │ │ ├── collision_tray_mid_017.obj
│ │ │ │ │ │ ├── collision_tray_mid_018.obj
│ │ │ │ │ │ ├── collision_tray_mid_019.obj
│ │ │ │ │ │ ├── collision_tray_mid_020.obj
│ │ │ │ │ │ ├── collision_tray_mid_021.obj
│ │ │ │ │ │ ├── collision_tray_mid_022.obj
│ │ │ │ │ │ ├── collision_tray_mid_023.obj
│ │ │ │ │ │ ├── collision_tray_mid_024.obj
│ │ │ │ │ │ ├── collision_tray_mid_025.obj
│ │ │ │ │ │ ├── collision_tray_mid_026.obj
│ │ │ │ │ │ ├── collision_tray_mid_027.obj
│ │ │ │ │ │ └── collision_tray_mid_plates_holder.obj
│ │ │ │ │ └── visual/
│ │ │ │ │ ├── dish_washer_body_001.obj
│ │ │ │ │ ├── dish_washer_bottom_001.obj
│ │ │ │ │ ├── dish_washer_bottom_cuttlery_basket_001.obj
│ │ │ │ │ ├── dish_washer_bottom_plates_holder_001.obj
│ │ │ │ │ ├── dish_washer_bottom_wheel.obj
│ │ │ │ │ ├── dish_washer_door_001.obj
│ │ │ │ │ ├── dish_washer_mid_001.obj
│ │ │ │ │ ├── dish_washer_mid_sprinkle.obj
│ │ │ │ │ └── dish_washer_top_001.obj
│ │ │ │ └── dishwasher.xml
│ │ │ ├── groceries/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── beer.obj
│ │ │ │ │ ├── cereal.obj
│ │ │ │ │ ├── crisps.obj
│ │ │ │ │ ├── ketchup.obj
│ │ │ │ │ ├── mustard.obj
│ │ │ │ │ └── soda.obj
│ │ │ │ ├── beer.xml
│ │ │ │ ├── cereal.xml
│ │ │ │ ├── crisps.xml
│ │ │ │ ├── detergent/
│ │ │ │ │ ├── assets/
│ │ │ │ │ │ ├── detergent.obj
│ │ │ │ │ │ ├── detergent_collision_001.obj
│ │ │ │ │ │ └── detergent_collision_002.obj
│ │ │ │ │ └── detergent.xml
│ │ │ │ ├── ketchup.xml
│ │ │ │ ├── mustard.xml
│ │ │ │ ├── soap/
│ │ │ │ │ ├── assets/
│ │ │ │ │ │ ├── soap.obj
│ │ │ │ │ │ ├── soap_collision_001.obj
│ │ │ │ │ │ └── soap_collision_002.obj
│ │ │ │ │ └── soap.xml
│ │ │ │ ├── soda.xml
│ │ │ │ └── wine/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── wine_bottle.obj
│ │ │ │ │ ├── wine_bottle_collision_001.obj
│ │ │ │ │ └── wine_bottle_collision_002.obj
│ │ │ │ └── wine.xml
│ │ │ ├── kitchen/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── drawer_600_full.obj
│ │ │ │ │ ├── drawer_600_half.obj
│ │ │ │ │ ├── drawer_600_quarter.obj
│ │ │ │ │ ├── drawer_handle.obj
│ │ │ │ │ ├── hanging_drawer_600.obj
│ │ │ │ │ └── hanging_drawer_600_glass.obj
│ │ │ │ ├── base_cabinet_600.xml
│ │ │ │ ├── open_shelf_600.xml
│ │ │ │ └── wall_cabinet_600.xml
│ │ │ ├── mug/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── mug.obj
│ │ │ │ │ ├── mug_collision_001.obj
│ │ │ │ │ ├── mug_collision_002.obj
│ │ │ │ │ ├── mug_collision_003.obj
│ │ │ │ │ ├── mug_collision_004.obj
│ │ │ │ │ ├── mug_collision_005.obj
│ │ │ │ │ ├── mug_collision_006.obj
│ │ │ │ │ ├── mug_collision_007.obj
│ │ │ │ │ ├── mug_collision_008.obj
│ │ │ │ │ ├── mug_collision_009.obj
│ │ │ │ │ ├── mug_collision_010.obj
│ │ │ │ │ ├── mug_collision_011.obj
│ │ │ │ │ ├── mug_collision_012.obj
│ │ │ │ │ ├── mug_collision_013.obj
│ │ │ │ │ ├── mug_collision_014.obj
│ │ │ │ │ ├── mug_collision_015.obj
│ │ │ │ │ ├── mug_collision_016.obj
│ │ │ │ │ ├── mug_collision_017.obj
│ │ │ │ │ └── mug_collision_018.obj
│ │ │ │ └── mug.xml
│ │ │ ├── pan/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── pan.obj
│ │ │ │ │ ├── pan_collision_handle.obj
│ │ │ │ │ ├── pan_collision_handle_001.obj
│ │ │ │ │ └── pan_collision_handle_002.obj
│ │ │ │ ├── pan.xml
│ │ │ │ └── pan_orignal.xml
│ │ │ ├── plate/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── plate_01.obj
│ │ │ │ │ ├── plate_01_collision.obj
│ │ │ │ │ ├── plate_01_collision_001.obj
│ │ │ │ │ ├── plate_01_collision_002.obj
│ │ │ │ │ ├── plate_01_collision_003.obj
│ │ │ │ │ ├── plate_01_collision_004.obj
│ │ │ │ │ ├── plate_01_collision_005.obj
│ │ │ │ │ ├── plate_01_collision_006.obj
│ │ │ │ │ ├── plate_01_collision_007.obj
│ │ │ │ │ ├── plate_01_collision_008.obj
│ │ │ │ │ ├── plate_01_collision_009.obj
│ │ │ │ │ ├── plate_01_collision_010.obj
│ │ │ │ │ ├── plate_01_collision_011.obj
│ │ │ │ │ └── plate_01_collision_012.obj
│ │ │ │ ├── plate.xml
│ │ │ │ └── plate_convex.xml
│ │ │ ├── sandwich/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── bread.obj
│ │ │ │ │ ├── cheese.obj
│ │ │ │ │ ├── sandwich_collision.obj
│ │ │ │ │ ├── sandwich_collision_rounded.obj
│ │ │ │ │ └── tomatoes.obj
│ │ │ │ ├── sandwich.xml
│ │ │ │ └── sandwich_toasted.xml
│ │ │ ├── saucepan/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── saucepan.obj
│ │ │ │ │ └── saucepan_collision_handle.obj
│ │ │ │ ├── saucepan.xml
│ │ │ │ └── saucepan_original.xml
│ │ │ ├── spatula/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── spatula.obj
│ │ │ │ │ ├── spatula_collision_001.obj
│ │ │ │ │ └── spatula_collision_002.obj
│ │ │ │ └── spatula.xml
│ │ │ ├── table/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── table.obj
│ │ │ │ │ ├── table_collision_001.obj
│ │ │ │ │ ├── table_collision_002.obj
│ │ │ │ │ ├── table_collision_003.obj
│ │ │ │ │ ├── table_collision_004.obj
│ │ │ │ │ ├── table_collision_005.obj
│ │ │ │ │ ├── table_collision_006.obj
│ │ │ │ │ ├── table_collision_007.obj
│ │ │ │ │ └── table_legs.obj
│ │ │ │ └── table.xml
│ │ │ └── table_dishwasher/
│ │ │ ├── assets/
│ │ │ │ ├── table_dishwasher.obj
│ │ │ │ ├── table_dishwasher_collision_001.obj
│ │ │ │ ├── table_dishwasher_collision_002.obj
│ │ │ │ ├── table_dishwasher_collision_003.obj
│ │ │ │ ├── table_dishwasher_collision_004.obj
│ │ │ │ ├── table_dishwasher_collision_005.obj
│ │ │ │ ├── table_dishwasher_collision_006.obj
│ │ │ │ └── table_dishwasher_legs.obj
│ │ │ └── table_dishwasher.xml
│ │ ├── robotiq_2f85/
│ │ │ ├── 2f85.xml
│ │ │ ├── 2f85_fine_manipulation.xml
│ │ │ └── assets/
│ │ │ ├── base.stl
│ │ │ ├── base_mount.stl
│ │ │ ├── coupler.stl
│ │ │ ├── driver.stl
│ │ │ ├── follower.stl
│ │ │ ├── pad.stl
│ │ │ ├── silicone_pad.stl
│ │ │ └── spring_link.stl
│ │ └── world.xml
│ ├── robots/
│ │ ├── __init__.py
│ │ ├── animated_legs.py
│ │ ├── config.py
│ │ ├── configs/
│ │ │ ├── __init__.py
│ │ │ ├── google_robot.py
│ │ │ ├── h1.py
│ │ │ ├── robotiq.py
│ │ │ └── stretch.py
│ │ ├── floating_base.py
│ │ ├── gripper.py
│ │ └── robot.py
│ └── utils/
│ ├── __init__.py
│ ├── callables_cache.py
│ ├── dof.py
│ ├── env_health.py
│ ├── env_utils.py
│ ├── observation_config.py
│ ├── physics_utils.py
│ ├── robot_highlighter.py
│ └── shared.py
├── demonstrations/
│ ├── __init__.py
│ ├── const.py
│ ├── demo.py
│ ├── demo_converter.py
│ ├── demo_player.py
│ ├── demo_recorder.py
│ ├── demo_store.py
│ └── utils.py
├── doc/
│ └── scripts/
│ ├── download_and_validate_demos.py
│ ├── download_demos.py
│ ├── measure_fps.py
│ ├── measure_fps_cams.py
│ ├── preview_renderer.py
│ ├── render_demos.py
│ └── render_previews.py
├── examples/
│ ├── launch_reach_target_pixels.py
│ ├── launch_reach_target_state.py
│ ├── record_and_replay_demo.py
│ └── replay_demo.py
├── setup.py
├── tests/
│ ├── __init__.py
│ ├── conftest.py
│ ├── data/
│ │ └── safetensors/
│ │ ├── 0_ReachTarget_JointPositionActionMode_state.safetensors
│ │ ├── 11_ReachTarget_TorqueActionMode_lightweight.safetensors
│ │ ├── 15_MovePlate_JointPositionActionMode_state.safetensors
│ │ ├── 17_MovePlate_JointPositionActionMode_pixel.safetensors
│ │ ├── 19_MovePlate_JointPositionActionMode_lightweight.safetensors
│ │ ├── 22_MovePlate_TorqueActionMode_state.safetensors
│ │ ├── 24_MovePlate_TorqueActionMode_pixel.safetensors
│ │ ├── 26_MovePlate_TorqueActionMode_lightweight.safetensors
│ │ ├── 2_ReachTarget_JointPositionActionMode_pixel.safetensors
│ │ ├── 30_StackBlocks_JointPositionActionMode_state.safetensors
│ │ ├── 32_StackBlocks_JointPositionActionMode_pixel.safetensors
│ │ ├── 34_StackBlocks_JointPositionActionMode_lightweight.safetensors
│ │ ├── 37_StackBlocks_TorqueActionMode_state.safetensors
│ │ ├── 39_StackBlocks_TorqueActionMode_pixel.safetensors
│ │ ├── 41_StackBlocks_TorqueActionMode_lightweight.safetensors
│ │ ├── 4_ReachTarget_JointPositionActionMode_lightweight.safetensors
│ │ ├── 7_ReachTarget_TorqueActionMode_state.safetensors
│ │ └── 9_ReachTarget_TorqueActionMode_pixel.safetensors
│ ├── pytest.ini
│ ├── tasks/
│ │ ├── test_move_plate.py
│ │ ├── test_stack_blocks.py
│ │ └── test_tasks.py
│ ├── test_action_modes.py
│ ├── test_demo_store.py
│ ├── test_demos.py
│ ├── test_envs.py
│ ├── test_observations.py
│ └── test_unstable_simulation.py
├── tools/
│ ├── __init__.py
│ ├── demo_player/
│ │ ├── __init__.py
│ │ ├── demo_converter_window.py
│ │ ├── demo_player_rendering.py
│ │ ├── demo_player_window.py
│ │ └── main.py
│ ├── demo_recorder/
│ │ ├── __init__.py
│ │ ├── demo_recorder_window.py
│ │ └── main.py
│ └── shared/
│ ├── __init__.py
│ ├── base_window.py
│ ├── primary_window.py
│ ├── settings_shelf.py
│ └── utils.py
└── vr/
├── Dockerfile
├── Makefile
├── README.md
├── __init__.py
├── disable_steamvr_windows.sh
├── docker-compose.yaml
├── ik/
│ ├── __init__.py
│ └── h1_upper_body_ik.py
├── pulse-client.conf
└── viewer/
├── __init__.py
├── control_profiles/
│ ├── __init__.py
│ ├── control_profile.py
│ ├── h1_floating.py
│ └── universal_floating.py
├── controller.py
├── full_screen_renderer.py
├── pyopenxr_to_mujoco_converter.py
├── vr_mujoco_renderer.py
├── vr_viewer.py
├── xmls/
│ ├── controller_left/
│ │ ├── assets/
│ │ │ └── controller.obj
│ │ └── controller_left.xml
│ └── controller_right/
│ ├── assets/
│ │ └── controller.obj
│ └── controller_right.xml
├── xr_context.py
└── xr_input.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/build.yaml
================================================
name: build
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
bigym:
runs-on: ubuntu-22.04
steps:
- name: Check out repository
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
libxml2-utils \
xvfb \
xauth \
libgl1-mesa-dev \
libgl1-mesa-glx \
libosmesa6-dev
python -m pip install --upgrade pip
pip install ".[dev]"
pip install pre-commit
- name: Run pre-commit checks
run: pre-commit run --all-files
- name: Run tests
env:
MUJOCO_GL: osmesa
run: |
xvfb-run -a -s "-screen 0 1280x1024x24 -ac" \
pytest tests/ \
-s \
-v \
--log-cli-level=INFO
================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
# C extensions
*.so
# Distribution / packaging
bin/
build/
develop-eggs/
dist/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# PyCharm
.idea
# VSCode
.vscode
================================================
FILE: .pre-commit-config.yaml
================================================
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: check-yaml
exclude: bamboo-specs/bamboo.yaml
- id: sort-simple-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-xml
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.272
hooks:
- id: ruff
# Ignoring unused imports within __init__.py files.
args: [--per-file-ignores, '*__init__.py:F401', --fix]
- repo: https://github.com/pycqa/pydocstyle
rev: "6.3.0"
hooks:
- id: pydocstyle
args: [ "--convention=google" ]
files: bigym|examples|vr|demonstrations|tools
- repo: https://github.com/lsst-ts/pre-commit-xmllint
rev: v1.0.0
hooks:
- id: format-xmllint
================================================
FILE: CHANGELOG.md
================================================
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- None.
### Changed
- None.
### Fixed
- None.
## 4.2.0
### Added
- Simplified the process of adding new models with the introduction of robot configurations.
- Enabled the ability to override the robot in the environment.
## 4.1.0
### Added
- Added DemoPlayer entity containing shortcuts to replay and validate demonstrations.
### Changed
- Adjusted stiffness of floating base positional actuators to reach target state with +-1mm precision.
## 4.0.0
### Added
- Added configurable floating base DOFs. By default, floating base has [X, Y, RZ] DOFs.
- Added new tasks.
- Added presets for environments.
### Changed
- Different decimation for absolute and delta action modes.
## 3.0.0
### Changed
- BiGym refactored to use [Mojo](https://github.com/stepjam/mojo).
## 2.12.0
### Added
- Added customizable `control_frequency` of the `BiGymEnv`.
### Changed
- Updated Demo Player.
## 2.11.0
### Changed
- Environment reset behaviour should be implemented in `on_reset` now instead of `reset_model`.
- Environment termination behaviour uses `_should_terminate` which should now be overridden in the task environment.
## 2.10.0
### Added
- Lightweight demos are automatically uploaded to Google Cloud Buckets when using `DemoStore.upload_demo` and `DemoStore.upload_demos`.
- `TooManyDemosRequestedError` is raised when requesting more demos than available in the bucket.
- `DemoNotFoundError` is raised when requesting demos when none are available in the bucket.
## 2.9.0
### Changed
- The observation vector of the `BiGymEnv` is now configured
using `ObservationConfig` and `CameraConfig` instead of flags.
## 2.8.0
### Added
- Added `DemoStore` to upload and download demonstrations from Google Cloud Buckets.
- Added `Lightweight` demo format to store only demo action, termination and truncation information.
## 2.7.1
### Added
- Implemented handling of `PhysicsError` resulting from an unstable state in the simulation.
Instead of raising an error, `UnstableSimulationWarning` is now raised.
If multiple `UnstableSimulationWarning` occur consecutively, `UnstableSimulationError` is raised.
The `is_healthy` property of the `BiGymEnv` now indicates the current state of the simulation.
### Changed
- Refactored utils file into separate modules.
### Fixed
- Fixed NumPy 1.25 `DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated.` for `move_plate_between_drainers.py`.
## 2.6.1
### Added
- Added demo replay utility: [replay_demos.py](tools/demo_player/replay_demos.py).
### Changed
- Wrist joints are now part of the arm instead of gripper.
- Order of arm joints and actuators is matching now.
- Removed EE pose action mode.
### Fixed
- Visual observations can now be collected simultaneously with rendering to the on-screen window.
## 2.5.1
### Fixed
- Fixed `block_until_reached` flag for absolute joint position control mode.
## 2.5.0
### Added
- Additional wrist DOF could be added to H1 model.
### Changed
- Updated the control range of grippers to a discrete mode ranging from 0 to 1.
## 2.4.0
### Added
- Added EE pose action mode.
### Changed
- Renamed and updated `put_plate_in_drainer` task to `move_plate_betweeen_drainers`.
- Renamed and updated `swipe_table` task to `stack_blocks`.
- Gripper control space is now always in the 0-1 range.
### Fixed
- When floating mode is enabled redundant joints are removed completely to prevent instability.
- Removed unnecessary rotation offsets of props to simplify manipulation.
## 2.3.0
### Added
- Added functionality to run BiGym environments in VR using pyopenxr. See [collect_demos.py](demonstrations/collect_demos.py).
### Changed
- `BiGymEnv._add_dynamic_objects()` is now an abstract method and should not be called in child classes.
## 2.2.0
### Added
- Added functionality to control seed of the BiGym environments.
- Added demo collection/replaying functionality and examples.
## 2.1.0
### Added
- Added control of H1 via mediapipe body tracking.
- Added new `SwipeTable` task.
## 2.0.0
### Added
- Added the `discrete_gripper` flag to control grippers in binary open-closed mode instead of positional mode.
### Changed
- Constructor now takes an `ActionMode`. Constructor arg `floating` has been removed and rolled into new `ActionMode` workflow.
- We now make use of `mjcf.physics` rather than directly using `mujoco.MjData`.
### Fixed
- Floating base is now controlled by positional actuators, and collisions are not ignored.
## 1.2.0
### Added
- Added new examples for tracking body with kinect to control H1.
## 1.1.1
### Fixed
- Fixed "floppy" legs when H1 is controlled in floating mode.
Enabling the floating mode now "freezes" the legs of the H1; collisions are disabled, and the motion range is limited to a minimum.
## 1.1.0
### Added
- Added new "Put plate in drainer" task.
- Added `is_gripper_holding_object` to `BiGymEnv` for checking if an object is grasped.
- Added `get_ee_pos` and `get_gripper_ee_pos` to `BiGymEnv` to retrieve the positions of H1 hands and grippers.
## 1.0.2
### Added
- Attached 2 2F-85 Robotiq grippers to H1.
### Fixed
- Automatically adjust home key frame of the H1 when attaching grippers.
## 1.0.1
### Fixed
- XML files not being included when installing.
## 1.0.0
### Added
- Head, left and right wrist cameras.
### Changed
- Constructor arguments to take in camera names.
## 0.2.0
### Added
- Floating base so that H1 can be controlled without legs; (x, y, theta) actions
- End-effector "sites".
- Added reach target task.
## 0.1.0
### Added
- Initial project code.
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
<h1>
<a href="#"><img alt="BiGym" src="doc/images/bigym.png" width="100%"></a>
</h1>
<p>
<a href="https://github.com/chernyadev/bigym/actions/workflows/build.yaml?query=branch%3Amaster" alt="GitHub Actions">
<img src="https://img.shields.io/github/actions/workflow/status/chernyadev/bigym/build.yaml?branch=master">
</a>
<a href="#contributing">
<img src="https://img.shields.io/badge/PRs-welcome-green.svg" alt="PRs" height="20">
</a>
</p>
[**BiGym: A Demo-Driven Mobile Bi-Manual Manipulation Benchmark**](https://arxiv.org/abs/2407.07788)\
[Nikita Cherniadev*](https://www.linkedin.com/in/nikita-cherniadev-8495417a/), [Nicholas Backshall*](https://www.linkedin.com/in/nicholas-backshall/?originalSubdomain=uk), [Xiao Ma*](https://yusufma03.github.io/), [Yunfan Lu](https://www.linkedin.com/in/yunfan-lu-90170992/?originalSubdomain=sg), [Younggyo Seo](https://younggyo.me/), [Stephen James](https://stepjam.github.io/)
BiGym is a new benchmark and learning environment for mobile bi-manual demo-driven robotic manipulation.
BiGym features 40 diverse tasks set in home environments, ranging from simple target reaching to complex kitchen cleaning. To capture the real-world performance accurately, we provide human-collected demonstrations for each task, reflecting the diverse modalities found in real-world robot trajectories. BiGym supports a variety of observations, including proprioceptive data and visual inputs such as RGB, and depth from 3 camera views.
For latest updates, check our project page: [https://chernyadev.github.io/bigym/](https://chernyadev.github.io/bigym/)
## Table of Contents
1. [Install](#install)
2. [Tasks](#tasks)
3. [Usage](#usage)
4. [Contributing](#contributing)
## Install
```commandline
pip install .
```
## Tasks
| Task | Description | Preview |
|-----------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| [ReachTarget](bigym/envs/reach_target.py) | Reach the target with either left or right wrist. | <img src="doc/images/tasks/task_preview_reach_target@720x720.png" width=320> |
| [ReachTargetSingle](bigym/envs/reach_target.py) | Reach the target with specific wrist. | <img src="doc/images/tasks/task_preview_reach_target_single@720x720.png" width=320> |
| [ReachTargetDual](bigym/envs/reach_target.py) | Reach 2 targets, one with each arm. | <img src="doc/images/tasks/task_preview_reach_target_dual@720x720.png" width=320> |
| [StackBlocks](bigym/envs/manipulation.py) | Move blocks across the table, and stack them in the target area. | <img src="doc/images/tasks/task_preview_stack_blocks@720x720.png" width=320> |
| [MovePlate](bigym/envs/move_plates.py) | Move the plate between two draining racks. | <img src="doc/images/tasks/task_preview_move_plate@720x720.png" width=320> |
| [MoveTwoPlates](bigym/envs/move_plates.py) | Move two plates simultaneously from one draining rack to the other. | <img src="doc/images/tasks/task_preview_move_two_plates@720x720.png" width=320> |
| [FlipCup](bigym/envs/manipulation.py) | Flip the cup, initially positioned upside down on the table, to an upright position. | <img src="doc/images/tasks/task_preview_flip_cup@720x720.png" width=320> |
| [FlipCutlery](bigym/envs/manipulation.py) | Take the cutlery from the static holder, flip it, and place it back into the holder. | <img src="doc/images/tasks/task_preview_flip_cutlery@720x720.png" width=320> |
| [DishwasherOpen](bigym/envs/dishwasher.py) | Open the dishwasher door and pull out all trays. | <img src="doc/images/tasks/task_preview_dishwasher_open@720x720.png" width=320> |
| [DishwasherClose](bigym/envs/dishwasher.py) | Push back all trays and close the door of the dishwasher. | <img src="doc/images/tasks/task_preview_dishwasher_close@720x720.png" width=320> |
| [DishwasherOpenTrays](bigym/envs/dishwasher.py) | Pull out the dishwasher’s trays with the door initially open. | <img src="doc/images/tasks/task_preview_dishwasher_open_trays@720x720.png" width=320> |
| [DishwasherCloseTrays](bigym/envs/dishwasher.py) | Push the dishwasher’s trays back with the door initially open. | <img src="doc/images/tasks/task_preview_dishwasher_close_trays@720x720.png" width=320> |
| [DishwasherLoadPlates](bigym/envs/dishwasher_plates.py) | Move plates from the rack to the lower tray of the dishwasher. | <img src="doc/images/tasks/task_preview_dishwasher_load_plates@720x720.png" width=320> |
| [DishwasherLoadCups](bigym/envs/dishwasher_cups.py) | Move cups from the table to the upper tray of the dishwasher. | <img src="doc/images/tasks/task_preview_dishwasher_load_cups@720x720.png" width=320> |
| [DishwasherLoadCutlery](bigym/envs/dishwasher_cutlery.py) | Move cutlery from the table holder to the dishwasher’s cutlery basket. | <img src="doc/images/tasks/task_preview_dishwasher_load_cutlery@720x720.png" width=320> |
| [DishwasherUnloadPlates](bigym/envs/dishwasher_plates.py) | Move plates from the tray of the dishwasher to a table rack. | <img src="doc/images/tasks/task_preview_dishwasher_unload_plates@720x720.png" width=320> |
| [DishwasherUnloadCups](bigym/envs/dishwasher_cups.py) | Move cups from the upper tray of the dishwasher to the table. | <img src="doc/images/tasks/task_preview_dishwasher_unload_cups@720x720.png" width=320> |
| [DishwasherUnloadCutlery](bigym/envs/dishwasher_cutlery.py) | Move cutlery from the cutlery basket to a tray on the table. | <img src="doc/images/tasks/task_preview_dishwasher_unload_cutlery@720x720.png" width=320> |
| [DishwasherUnloadPlatesLong](bigym/envs/dishwasher_plates.py) | A full task of unloading a plate: picking up the plate from dishwasher, placing this plate into the rack located in the closed wall cabinet, and closing the dishwasher and cupboard. | <img src="doc/images/tasks/task_preview_dishwasher_unload_plates_long@720x720.png" width=320> |
| [DishwasherUnloadCupsLong](bigym/envs/dishwasher_cups.py) | A full task of unloading a cup: picking up the cup, placing it inside the closed wall cabinet, and closing the dishwasher and cupboard. | <img src="doc/images/tasks/task_preview_dishwasher_unload_cups_long@720x720.png" width=320> |
| [DishwasherUnloadCutleryLong](bigym/envs/dishwasher_cutlery.py) | A full task of unloading a cutlery: picking up a cutlery, placing it into the cutlery tray inside the closed drawer, and closing the dishwasher and drawer. | <img src="doc/images/tasks/task_preview_dishwasher_unload_cutlery_long@720x720.png" width=320> |
| [DrawerTopOpen](bigym/envs/cupboards.py) | Open the top drawer of the kitchen cabinet. | <img src="doc/images/tasks/task_preview_drawer_top_open@720x720.png" width=320> |
| [DrawerTopClose](bigym/envs/cupboards.py) | Close the top drawer of the kitchen cabinet. | <img src="doc/images/tasks/task_preview_drawer_top_close@720x720.png" width=320> |
| [DrawersAllOpen](bigym/envs/cupboards.py) | Open all sliding drawers of the kitchen cabinet. | <img src="doc/images/tasks/task_preview_drawers_all_open@720x720.png" width=320> |
| [DrawersAllClose](bigym/envs/cupboards.py) | Close all sliding drawers of the kitchen cabinet. | <img src="doc/images/tasks/task_preview_drawers_all_close@720x720.png" width=320> |
| [WallCupboardOpen](bigym/envs/cupboards.py) | Open doors of the wall cabinet. | <img src="doc/images/tasks/task_preview_wall_cupboard_open@720x720.png" width=320> |
| [WallCupboardClose](bigym/envs/cupboards.py) | Close doors of the wall cabinet. | <img src="doc/images/tasks/task_preview_wall_cupboard_close@720x720.png" width=320> |
| [CupboardsOpenAll](bigym/envs/cupboards.py) | Open all drawers and doors of the kitchen set. | <img src="doc/images/tasks/task_preview_cupboards_open_all@720x720.png" width=320> |
| [CupboardsCloseAll](bigym/envs/cupboards.py) | Close all drawers and doors of the kitchen set. | <img src="doc/images/tasks/task_preview_cupboards_close_all@720x720.png" width=320> |
| [PutCups](bigym/envs/pick_and_place.py) | Pick up cups from the table and put them into the closed wall cabinet. | <img src="doc/images/tasks/task_preview_put_cups@720x720.png" width=320> |
| [TakeCups](bigym/envs/pick_and_place.py) | Take two cups out from the closed wall cabinet and put them on the table. | <img src="doc/images/tasks/task_preview_take_cups@720x720.png" width=320> |
| [PickBox](bigym/envs/pick_and_place.py) | Pick up a large box from the floor and place it on the counter. | <img src="doc/images/tasks/task_preview_pick_box@720x720.png" width=320> |
| [StoreBox](bigym/envs/pick_and_place.py) | Move a large box from the counter to the shelf in the cabinet below. | <img src="doc/images/tasks/task_preview_store_box@720x720.png" width=320> |
| [SaucepanToHob](bigym/envs/pick_and_place.py) | Take the saucepan from the closed cabinet and place it on the hob. | <img src="doc/images/tasks/task_preview_saucepan_to_hob@720x720.png" width=320> |
| [StoreKitchenware](bigym/envs/pick_and_place.py) | Take all items from the hob and place them in the cabinet below. | <img src="doc/images/tasks/task_preview_store_kitchenware@720x720.png" width=320> |
| [ToastSandwich](bigym/envs/pick_and_place.py) | Use the spatula to put the sandwich on the frying pan. | <img src="doc/images/tasks/task_preview_toast_sandwich@720x720.png" width=320> |
| [FlipSandwich](bigym/envs/pick_and_place.py) | Flip the sandwich in the frying pan using the spatula. | <img src="doc/images/tasks/task_preview_flip_sandwich@720x720.png" width=320> |
| [RemoveSandwich](bigym/envs/pick_and_place.py) | Take the sandwich out of the frying pan. | <img src="doc/images/tasks/task_preview_remove_sandwich@720x720.png" width=320> |
| [GroceriesStoreLower](bigym/envs/groceries.py) | Place a random set of groceries in the cabinets below the counter. | <img src="doc/images/tasks/task_preview_groceries_store_lower@720x720.png" width=320> |
| [GroceriesStoreUpper](bigym/envs/groceries.py) | Place a random set of groceries in cabinets and shelves on the wall. | <img src="doc/images/tasks/task_preview_groceries_store_upper@720x720.png" width=320> |
## Usage
Directly instantiate the task of interest. Tasks are located in [bigym/envs/](bigym/envs/).
```python
from bigym.action_modes import TorqueActionMode
from bigym.envs.reach_target import ReachTarget
from bigym.utils.observation_config import ObservationConfig, CameraConfig
env = ReachTarget(
action_mode=TorqueActionMode(floating_base=True),
observation_config=ObservationConfig(
cameras=[
CameraConfig(
name="head",
rgb=True,
depth=False,
resolution=(128, 128),
)
],
),
render_mode=None,
)
```
Use `ActionModes` to parameterise how you want to control your robot.
## Working with demonstrations
### [Demo Store](demonstrations/demo_store.py)
Please see simple example here: [examples/replay_demo.py](examples/replay_demo.py).
Demonstrations are automatically downloaded from GitHub releases.
When demos are requested by calling `DemoStore.get_demos()`. The current dataset will be cached locally at `$HOME/.bigym/v0.0.0`.
Demonstrations with custom observations and frequency are also cached to `$HOME/.bigym/v0.0.0`.
**⚠️ Warning:** We are working on the dataset. Not all demonstrations will result in successful completion of the task. Please validate before use.
**⚠️ Warning:** The current dataset includes demonstrations for the following action modes only:
- `JointPositionActionMode(floating_base=True, absolute=True)`
- `JointPositionActionMode(floating_base=True, absolute=False)`
### [Demo Player](tools/demo_player/main.py)
Replay existing demos using GUI player.
```bash
python tools/demo_player/main.py
```
<img src="doc/images/demo_player/player_window.png" width=360>
<img src="doc/images/demo_player/player_mujoco.png" width=360>
### [VR Demo Recorder](tools/demo_recorder/main.py)
Record new demos in VR. Follow [VR README](vr/README.md) to configure docker container to run this tool.
```bash
python tools/demo_recorder/main.py
```
<img src="doc/images/demo_recorder/demo_recorder.png" width=360>
## Contributing
On each PR, please ensure to bump the:
- **Major** version if you alter the existing interface in any way.
- **Minor** version if you have added new features (which didn't break the existing interface)
- **Patch** version for bug fixes.
Please ensure that you pass pre-commits before opening a PR: `pre-commit run --all-files` and that you pass all tests: `pytest tests/ --run-slow`.
## Licenses
- [BiGym License (Apache 2.0)](LICENSE) - This repository
- [Mujoco Menagerie (Apache 2.0)](https://github.com/google-deepmind/mujoco_menagerie/blob/main/LICENSE) - Models of robots and grippers
- [3D Assets Attributions (CC0, CC BY 4.0, CC BY NC 4.0)](bigym/envs/xmls/3D_MODELS_ATTRIBUTION.md) - 3D Assets
## Citation
If you find our work helpful, please kindly cite us
```bibtex
@article{chernyadev2024bigym,
title={BiGym: A Demo-Driven Mobile Bi-Manual Manipulation Benchmark},
author={Chernyadev, Nikita and Backshall, Nicholas and Ma, Xiao and Lu, Yunfan and Seo, Younggyo and James, Stephen},
journal={arXiv preprint arXiv:2407.07788},
year={2024}
}
```
================================================
FILE: bigym/__init__.py
================================================
"""Init."""
__version__ = "4.1.0"
================================================
FILE: bigym/action_modes.py
================================================
"""Action modes for H1."""
from __future__ import annotations
from enum import Enum
from typing import TYPE_CHECKING
import warnings
from abc import abstractmethod, ABC
from typing import Optional
import numpy as np
from gymnasium import spaces
from mojo import Mojo
from bigym.const import TOLERANCE_ANGULAR
from bigym.utils.physics_utils import (
is_target_reached,
)
if TYPE_CHECKING:
from bigym.robots.robot import Robot
class TargetStateNotReachedWarning(Warning):
"""Warning raised when the target state is not reached within the maximum steps."""
pass
class PelvisDof(Enum):
"""Set of floating base DOFs."""
X = "pelvis_x"
Y = "pelvis_y"
Z = "pelvis_z"
RZ = "pelvis_rz"
DEFAULT_DOFS = [PelvisDof.X, PelvisDof.Y, PelvisDof.RZ]
class ActionMode(ABC):
"""Base action mode class used for controlling H1."""
def __init__(
self,
floating_base: bool = True,
floating_dofs: Optional[list[PelvisDof]] = None,
):
"""Init.
:param floating_base: If True, then legs are frozen, and the robot base
controlled by positional actuators.
If False, then user has full control of legs (i.e. for whole-body control).
:param floating_dofs: Set of floating DOFs. By default, it is: [X, Y, RZ].
"""
self._floating_base = floating_base
self._floating_dofs = DEFAULT_DOFS if floating_dofs is None else floating_dofs
# Will be assigned later
self._mojo: Optional[Mojo] = None
self._robot: Optional[Robot] = None
def bind_robot(self, robot: Robot, mojo: Mojo):
"""Bind action mode to robot."""
self._robot = robot
self._mojo = mojo
@property
def floating_base(self) -> bool:
"""Is floating base enabled."""
return self._floating_base
@property
def floating_dofs(self) -> list[PelvisDof]:
"""Set of floating DOFs."""
return self._floating_dofs
@abstractmethod
def action_space(
self, action_scale: float, seed: Optional[int] = None
) -> spaces.Box:
"""The action space for this action mode."""
pass
@abstractmethod
def step(self, action: np.ndarray):
"""Apply the control command and step the physics.
Note: This function has the responsibility of calling `mujoco.mj_step`.
:param action: The entire action passed to the action mode.
"""
pass
@abstractmethod
def reset(self, reset_state: np.ndarray):
"""Reset state of the robot accordingly to the action mode.
:param reset_state: Target reset state of robot actuators.
"""
pass
class TorqueActionMode(ActionMode):
"""Control all joints through torque control.
Enables the user to control joints using torque values.
Notes:
- Grippers are controlled in positional mode.
- Joints of the 'floating_base' are always controlled in delta position mode.
"""
def action_space(
self, action_scale: float, seed: Optional[int] = None
) -> spaces.Box:
"""See base."""
bounds = []
if self.floating_base:
action_bounds = self._robot.floating_base.get_action_bounds()
action_bounds = [np.array(b) * action_scale for b in action_bounds]
bounds.extend(action_bounds)
for actuator in self._robot.limb_actuators:
action_bounds = np.array(actuator.ctrlrange)
bounds.append(action_bounds)
for _, gripper in self._robot.grippers.items():
bounds.append(gripper.range)
bounds = np.array(bounds).copy().astype(np.float32)
low, high = bounds.T
return spaces.Box(
low=low,
high=high,
dtype=np.float32,
seed=seed,
)
def step(self, action: np.ndarray):
"""See base."""
if self.floating_base:
base_action = action[: self._robot.floating_base.dof_amount]
action = action[self._robot.floating_base.dof_amount :]
self._robot.floating_base.set_control(base_action)
for i, actuator in enumerate(self._robot.limb_actuators):
self._mojo.physics.bind(actuator).ctrl = action[i]
gripper_actions = action[-len(self._robot.grippers) :]
for side, action in zip(self._robot.grippers, gripper_actions):
self._robot.grippers[side].set_control(action)
self._mojo.step()
def reset(self, reset_state: np.ndarray):
"""See base."""
if len(reset_state) != len(self._robot.limb_actuators):
raise ValueError(
f"Mismatch between reset_state length "
f"({len(reset_state)}) "
f"and number of actuators ({len(self._robot.limb_actuators)}). "
f"Ensure reset_state matches the actuators count in the model."
)
for value, actuator in zip(reset_state, self._robot.limb_actuators):
if actuator.joint:
joint = self._mojo.physics.bind(actuator.joint)
joint.qpos = value
joint.qvel *= 0
joint.qacc *= 0
elif actuator.tendon:
warnings.warn(
f"Tendon actuators are not fully supported "
f"for {self.__class__.__name__} action mode."
)
class JointPositionActionMode(ActionMode):
"""Control all joints through joint position.
Allows to control joint positions, supporting both absolute and delta positions.
For absolute control, set 'absolute' to True. If the floating base is enabled,
only delta position control is applied to it.
Notes:
- `block_until_reached` does not guarantee reaching the target position because
the target position could be unreachable due to collisions.
- Joints of the `floating_base` are always controlled in delta position mode.
"""
MAX_STEPS = 200
def __init__(
self,
absolute: bool = False,
block_until_reached: bool = False,
floating_base: bool = True,
floating_dofs: list[PelvisDof] = None,
):
"""See base.
:param absolute: Use absolute or delta joint positions.
:param block_until_reached: Continue stepping until the target
position is reached or the step threshold is exceeded.
"""
super().__init__(
floating_base=floating_base,
floating_dofs=floating_dofs,
)
self.absolute = absolute
self.block_until_reached = block_until_reached
def action_space(
self, action_scale: float, seed: Optional[int] = None
) -> spaces.Box:
"""See base."""
bounds = []
if self.floating_base:
action_bounds = self._robot.floating_base.get_action_bounds()
action_bounds = [np.array(b) * action_scale for b in action_bounds]
bounds.extend(action_bounds)
for actuator in self._robot.limb_actuators:
action_bounds = np.array(
self._robot.get_limb_control_range(actuator, self.absolute)
)
action_bounds *= 1 if self.absolute else action_scale
bounds.append(action_bounds)
for _, gripper in self._robot.grippers.items():
bounds.append(gripper.range)
bounds = np.array(bounds).copy().astype(np.float32)
low, high = bounds.T
return spaces.Box(
low=low,
high=high,
dtype=np.float32,
seed=seed,
)
def step(self, action: np.ndarray):
"""See base."""
if self.floating_base:
base_action = action[: self._robot.floating_base.dof_amount]
action = action[self._robot.floating_base.dof_amount :]
self._robot.floating_base.set_control(base_action)
for i, actuator in enumerate(self._robot.limb_actuators):
actuator = self._mojo.physics.bind(actuator)
actuator.ctrl = action[i] if self.absolute else actuator.ctrl + action[i]
gripper_actions = action[-len(self._robot.grippers) :]
for side, action in zip(self._robot.grippers, gripper_actions):
self._robot.grippers[side].set_control(action)
if self.block_until_reached:
self._step_until_reached()
else:
self._mojo.step()
def reset(self, reset_state: np.ndarray):
"""See base."""
if len(reset_state) != len(self._robot.limb_actuators):
raise ValueError(
f"Mismatch between reset_state length "
f"({len(reset_state)}) "
f"and number of actuators ({len(self._robot.limb_actuators)}). "
f"Ensure reset_state matches the actuators count in the model."
)
for value, actuator in zip(reset_state, self._robot.limb_actuators):
if actuator.joint:
bound_joint = self._mojo.physics.bind(actuator.joint)
bound_joint.qpos = value
bound_joint.qvel *= 0
bound_joint.qacc *= 0
elif actuator.tendon:
if actuator.tendon.joint is None or len(actuator.tendon.joint) == 0:
raise RuntimeError(
"Currently only fixed tendons with joints are supported."
)
joint_value = value / len(actuator.tendon.joint)
for tendon_joint in actuator.tendon.joint:
value_coefficient = tendon_joint.coef
bound_joint = self._mojo.physics.bind(tendon_joint.joint)
bound_joint.qpos = joint_value / value_coefficient
bound_joint.qvel *= 0
bound_joint.qacc *= 0
bound_actuator = self._mojo.physics.bind(actuator)
bound_actuator.ctrl = value
def _step_until_reached(self):
"""Step physics until the target position is reached."""
steps_counter = 0
while True:
self._mojo.step()
steps_counter += 1
if self._is_target_state_reached() or steps_counter >= self.MAX_STEPS:
if steps_counter >= self.MAX_STEPS:
warnings.warn(
f"Failed to reach target state in " f"{self.MAX_STEPS} steps!",
TargetStateNotReachedWarning,
)
break
def _is_target_state_reached(self):
if self.floating_base:
if not self._robot.floating_base.is_target_reached:
return False
for actuator in self._robot.limb_actuators:
if not is_target_reached(actuator, self._mojo.physics, TOLERANCE_ANGULAR):
return False
return True
================================================
FILE: bigym/bigym_env.py
================================================
"""Core BiGym env functionality."""
from __future__ import annotations
import logging
from pathlib import Path
from typing import Any, Optional, Type
import mujoco
import numpy as np
import gymnasium as gym
from gymnasium import spaces
from mojo import Mojo
from mojo.elements import Geom, Camera
from bigym.action_modes import ActionMode
from bigym.const import WORLD_MODEL
from bigym.envs.props.preset import Preset
from bigym.robots.configs.h1 import H1
from bigym.robots.robot import Robot
from bigym.bigym_renderer import BiGymRenderer
from bigym.utils.callables_cache import CallablesCache
from bigym.utils.env_health import EnvHealth
from bigym.utils.observation_config import ObservationConfig
CONTROL_FREQUENCY_MAX = 500
CONTROL_FREQUENCY_MIN = 20
PHYSICS_DT = 0.002
MAX_DISTANCE_FROM_ORIGIN = 10
SPARSE_REWARD_FACTOR = 1
class BiGymEnv(gym.Env):
"""Core BiGym environment which loads in common robot across all tasks."""
metadata = {
"render_modes": ["human", "rgb_array", "depth_array"],
"render_fps": 1 / PHYSICS_DT,
}
_ENV_CAMERAS = ["external"]
_MODEL_PATH: Path = WORLD_MODEL
_PRESET_PATH: Optional[Path] = None
_FLOOR = "floor"
DEFAULT_ROBOT = H1
RESET_ROBOT_POS = np.array([0, 0, 0])
RESET_ROBOT_QUAT = np.array([1, 0, 0, 0])
def __init__(
self,
action_mode: ActionMode,
observation_config: ObservationConfig = ObservationConfig(),
render_mode: Optional[str] = None,
start_seed: Optional[int] = None,
control_frequency: int = CONTROL_FREQUENCY_MAX,
robot_cls: Optional[Type[Robot]] = None,
):
"""Init.
:param action_mode: The action mode of the robot. Use this to configure how
you plan to control the robot. E.g. joint position, delta ee pose, ect.
:param observation_config: Observations configuration. Use this to configure
collected data.
:param render_mode: The render mode for mujoco. Options are
"human", "rgb_array" or "depth_array". If None, the default render mode
will be used.
:param start_seed: The seed to start the environment with. If None, a random
seed will be used.
:param control_frequency: Control loop frequency, 500 Hz by default.
:param robot_cls: Environment robot class override.
"""
# Tracks physics simulation stability
self._env_health = EnvHealth()
# Caches results valid for one environment step
self._step_cache = CallablesCache()
self._observation_config = observation_config
self.action_mode = action_mode
if start_seed is None:
start_seed = np.random.randint(2**32)
if not isinstance(start_seed, int):
raise ValueError("Expected start_seed to be an integer.")
self._next_seed = start_seed
self._current_seed = None
assert CONTROL_FREQUENCY_MIN <= control_frequency <= CONTROL_FREQUENCY_MAX, (
f"Control frequency must be in "
f"{CONTROL_FREQUENCY_MIN}-{CONTROL_FREQUENCY_MAX} range."
)
self._control_frequency = control_frequency
self._sub_steps_count = int(
np.round(CONTROL_FREQUENCY_MAX / self._control_frequency)
)
self._mojo = Mojo(str(self._MODEL_PATH), timestep=PHYSICS_DT)
self._robot = (robot_cls or self.DEFAULT_ROBOT)(self.action_mode, self._mojo)
self._preset = Preset(self._mojo, self._PRESET_PATH)
self._initialize_env()
self._floor = Geom.get(self._mojo, self._FLOOR)
self.action_space: spaces.Box = self.action_mode.action_space(
action_scale=self._sub_steps_count, seed=self._next_seed
)
self._action: np.ndarray = np.zeros_like(self.action_space.low)
self.observation_space: spaces.Space = self.get_observation_space()
assert self.metadata["render_modes"] == [
"human",
"rgb_array",
"depth_array",
], self.metadata["render_modes"]
self.render_mode = render_mode
# Validate cameras configuration
available_cameras = set(self._ENV_CAMERAS + self._robot.config.cameras)
for camera_config in self._observation_config.cameras:
assert camera_config.name in available_cameras
# Mapping original camera names to full identifiers
self._cameras_map = self._initialize_cameras()
self.mujoco_renderer: Optional[BiGymRenderer] = None
self.obs_renderers: Optional[dict[tuple[int, int], mujoco.Renderer]] = {}
self._initialize_renderers()
@property
def task_name(self) -> str:
"""Returns the class name of the environment."""
return self.__class__.__name__
@property
def _use_pixels(self):
"""Returns True if the environment uses pixels."""
return len(self.observation_config.cameras) > 0
@property
def seed(self) -> Optional[int]:
"""Initial seed of the environment."""
return self._current_seed
@property
def success(self) -> bool:
"""Check if current step is successful."""
return bool(self._step_cache.get(self._success))
@property
def fail(self) -> bool:
"""Check if current step is successful."""
return bool(self._step_cache.get(self._fail))
@property
def reward(self) -> float:
"""Get current step reward."""
return float(self._step_cache.get(self._reward))
@property
def terminate(self) -> bool:
"""Get current step termination condition."""
return bool(self.success or self.fail)
@property
def truncate(self) -> bool:
"""Get current step truncation condition."""
return bool(not self.is_healthy)
@property
def is_healthy(self) -> bool:
"""Checks if the simulation is currently healthy."""
return bool(self._env_health.is_healthy)
@property
def observation_config(self) -> ObservationConfig:
"""Get the observation configuration."""
return self._observation_config
@property
def control_frequency(self):
"""Control frequency of the environment."""
return self._control_frequency
@property
def robot(self) -> Robot:
"""Get robot."""
return self._robot
@property
def floor(self) -> Geom:
"""Get environment floor."""
return self._floor
@property
def mojo(self) -> Mojo:
"""Get Mojo."""
return self._mojo
@property
def action(self) -> np.ndarray:
"""Get last executed action."""
return self._action.copy()
def _initialize_renderers(self):
self._close_renderers()
self.mujoco_renderer: BiGymRenderer = BiGymRenderer(self._mojo)
for camera_config in self._observation_config.cameras:
resolution = camera_config.resolution
if resolution in self.obs_renderers:
continue
self.obs_renderers[resolution] = mujoco.Renderer(
self._mojo.model, resolution[0], resolution[1]
)
def _initialize_cameras(self) -> dict[str, tuple[int, Camera]]:
cameras_map: dict[str, tuple[int, Camera]] = {}
for camera_name in self._ENV_CAMERAS:
camera: Camera = Camera.get(
self._mojo, camera_name, self._mojo.root_element
)
cameras_map[camera_name] = (camera.id, camera)
for robot_camera in self._robot.cameras:
cameras_map[robot_camera.mjcf.name] = (
robot_camera.id,
robot_camera,
)
for camera_config in self._observation_config.cameras:
_, camera = cameras_map[camera_config.name]
if camera_config.pos is not None:
camera.set_position(np.array(camera_config.pos))
if camera_config.quat is not None:
camera.set_quaternion(np.array(camera_config.quat))
return cameras_map
def _close_renderers(self):
if self.mujoco_renderer is not None:
self.mujoco_renderer.close()
for renderer in self.obs_renderers.values():
renderer.close()
self.mujoco_renderer = None
self.obs_renderers.clear()
def _initialize_env(self):
"""Can be overwritten to add task specific items to scene."""
pass
def get_observation_space(self) -> spaces.Space:
"""Get observation space."""
obs_dict = {}
if self._observation_config.proprioception:
obs_dict = {
"proprioception": spaces.Box(
low=-np.inf,
high=np.inf,
shape=(len(self._robot.qpos) + len(self._robot.qvel),),
dtype=np.float32,
),
"proprioception_grippers": spaces.Box(
low=0,
high=1,
shape=(len(self.robot.qpos_grippers),),
dtype=np.float32,
),
}
if self.robot.floating_base:
obs_dict.update(
{
"proprioception_floating_base": spaces.Box(
low=-np.inf,
high=np.inf,
shape=(len(self.robot.floating_base.qpos),),
dtype=np.float32,
),
"proprioception_floating_base_actions": spaces.Box(
low=-np.inf,
high=np.inf,
shape=(
len(self.robot.floating_base.get_accumulated_actions),
),
dtype=np.float32,
),
}
)
if self._use_pixels:
for camera in self.observation_config.cameras:
if camera.rgb:
obs_dict[f"rgb_{camera.name}"] = spaces.Box(
low=0, high=255, shape=(3, *camera.resolution), dtype=np.uint8
)
if camera.depth:
obs_dict[f"depth_{camera.name}"] = spaces.Box(
# todo: check if this is the correct range
low=0,
high=1,
shape=camera.resolution,
dtype=np.float32,
)
if self._observation_config.privileged_information:
obs_dict.update(self._get_task_privileged_obs_space())
return spaces.Dict(obs_dict)
def _get_task_privileged_obs_space(self) -> dict[str, Any]:
"""Get the task privileged observation space."""
return {}
def get_observation(self) -> dict[str, np.ndarray]:
"""Get the observation."""
obs = {}
if self._observation_config.proprioception:
obs |= self._get_proprioception_obs()
if self._use_pixels:
obs |= self._get_visual_obs()
if self._observation_config.privileged_information:
obs |= self._get_task_privileged_obs()
return obs
def _get_task_info(self) -> dict[str, Any]:
"""Get the task info dict."""
return {}
def get_info(self) -> dict[str, Any]:
"""Get info dict."""
info = self._get_task_info()
info.update({"task_success": float(self.success)})
return info
def _get_proprioception_obs(self) -> dict[str, Any]:
obs = {
"proprioception": np.concatenate(
[self._robot.qpos, self._robot.qvel]
).astype(np.float32),
"proprioception_grippers": np.array(self.robot.qpos_grippers).astype(
np.float32
),
}
if self.robot.floating_base:
obs["proprioception_floating_base"] = np.array(
self.robot.floating_base.qpos
).astype(np.float32)
obs["proprioception_floating_base_actions"] = np.array(
self.robot.floating_base.get_accumulated_actions
).astype(np.float32)
return obs
def _get_visual_obs(self) -> dict[str, Any]:
"""Get the visual observation."""
obs = {}
for camera_config in self._observation_config.cameras:
obs_renderer = self.obs_renderers[camera_config.resolution]
obs_renderer.update_scene(
self._mojo.data, self._cameras_map[camera_config.name][0]
)
if camera_config.rgb:
rgb = obs_renderer.render()
obs[f"rgb_{camera_config.name}"] = np.moveaxis(rgb, -1, 0)
if camera_config.depth:
obs_renderer.enable_depth_rendering()
obs[f"depth_{camera_config.name}"] = obs_renderer.render()
obs_renderer.disable_depth_rendering()
return obs
def _get_task_privileged_obs(self) -> dict[str, Any]:
"""Get the task privileged observation."""
return {}
def _update_seed(self, override_seed=None):
"""Update the seed for the environment.
Args:
override_seed: If not None, the next seed will be set to this value.
"""
if override_seed is not None:
if not isinstance(override_seed, int):
logging.warning(
"Expected override_seed to be an integer. Casting to int."
)
override_seed = int(override_seed)
self._next_seed = override_seed
self.action_space = self.action_mode.action_space(
action_scale=self._sub_steps_count, seed=override_seed
)
self._current_seed = self._next_seed
assert self._current_seed is not None
self._next_seed = np.random.randint(2**32)
np.random.seed(self._current_seed)
def reset(self, *, seed: Optional[int] = None, options: Optional[dict] = None):
"""Reset the environment.
Args:
seed: If not None, the environment will be reset with this seed.
options: Additional information to specify how the environment is reset
(optional, depending on the specific environment).
"""
self._env_health.reset()
self._update_seed(override_seed=seed)
self._mojo.physics.reset()
self._action = np.zeros_like(self._action)
self._robot.reset(self.RESET_ROBOT_POS, self.RESET_ROBOT_QUAT)
self._on_reset()
return self.get_observation(), self.get_info()
def _on_reset(self):
"""Custom environment reset behaviour."""
pass
def _on_step(self):
"""Custom environment behaviour after stepping."""
pass
def render(self):
"""Renders a frame of the simulation."""
return self.mujoco_renderer.render(self.render_mode)
def step(
self, action: np.ndarray, fast: bool = False
) -> tuple[Any, float, bool, bool, dict]:
"""Step the environment.
Args:
action: Action to take.
fast: If True, perform the environment step without processing observations
and return default values. Useful when performance is crucial,
but observations are not required, e.g., demo collection in VR.
Returns:
tuple: (observation, reward, terminated, truncated, info).
"""
self._step_cache.clean()
self._step_mujoco_simulation(action)
self._on_step()
self._action = action
if fast:
return {}, 0, False, False, {}
else:
return (
self.get_observation(),
self.reward,
self.terminate,
self.truncate,
self.get_info(),
)
def _step_mujoco_simulation(self, action):
"""Step the mujoco simulation."""
if action.shape != self.action_space.shape:
raise ValueError(
f"Action shape mismatch: "
f"expected {self.action_space.shape}, but got {action.shape}."
)
if np.any(action < self.action_space.low) or np.any(
action > self.action_space.high
):
clipped_action = np.clip(
action, self.action_space.low, self.action_space.high
)
raise ValueError(
f"Action {action} is out of the action space bounds. "
f"Overhead: {action - clipped_action}"
)
with self._env_health.track():
for i in range(self._sub_steps_count):
if i == 0:
self.action_mode.step(action)
else:
self._mojo.step()
mujoco.mj_rnePostConstraint(self._mojo.model, self._mojo.data)
def _success(self) -> bool:
"""Check if the episode is successful."""
return False
def _fail(self) -> bool:
"""Check if the episode is failed."""
return (
np.linalg.norm(self._robot.pelvis.get_position()) > MAX_DISTANCE_FROM_ORIGIN
)
def _reward(self) -> float:
"""Get current episode reward."""
return float(self.success) * SPARSE_REWARD_FACTOR
def close(self):
"""Close environment."""
self._close_renderers()
================================================
FILE: bigym/bigym_renderer.py
================================================
"""Fix to be able to render to on- and off- screen at the same time."""
import time
import glfw
import mujoco
from gymnasium.envs.mujoco.mujoco_rendering import (
MujocoRenderer,
WindowViewer,
OffScreenViewer,
BaseRender,
)
from mojo import Mojo
class BiGymRenderer(MujocoRenderer):
"""Custom mujoco_rendering.MujocoRenderer with fixes.
Notes:
- Allows to render in human mode along with visual observations.
"""
def __init__(self, mojo: Mojo):
"""Init."""
super().__init__(mojo.model, mojo.data)
def _get_viewer(self, render_mode: str) -> BaseRender:
"""See base."""
self.viewer = self._viewers.get(render_mode)
if self.viewer is None:
if render_mode == "human":
self.viewer = BiGymWindowViewer(self.model, self.data)
elif render_mode in {"rgb_array", "depth_array"}:
self.viewer = OffScreenViewer(self.model, self.data)
else:
raise AttributeError(
f"Unexpected mode: {render_mode}, "
f"expected modes: human, rgb_array, or depth_array"
)
self._set_cam_config()
self._viewers[render_mode] = self.viewer
self.viewer.make_context_current()
return self.viewer
def get_viewer(self, render_mode: str) -> BaseRender:
"""Get viewer for specified render mode."""
return self._get_viewer(render_mode)
class BiGymWindowViewer(WindowViewer):
"""Custom mujoco_rendering.WindowViewer with fixes.
Notes:
- Fixes GUI overlap when viewer is paused.
"""
def render(self):
"""See base."""
def update():
# fill overlay items
self._create_overlay()
render_start = time.time()
if self.window is None:
return
elif glfw.window_should_close(self.window):
glfw.destroy_window(self.window)
glfw.terminate()
self.viewport.width, self.viewport.height = glfw.get_framebuffer_size(
self.window
)
# update scene
mujoco.mjv_updateScene(
self.model,
self.data,
self.vopt,
mujoco.MjvPerturb(),
self.cam,
mujoco.mjtCatBit.mjCAT_ALL.value,
self.scn,
)
# marker items
for marker in self._markers:
self._add_marker_to_scene(marker)
# render
mujoco.mjr_render(self.viewport, self.scn, self.con)
# overlay items
if not self._hide_menu:
for gridpos, [t1, t2] in self._overlays.items():
mujoco.mjr_overlay(
mujoco.mjtFontScale.mjFONTSCALE_150,
gridpos,
self.viewport,
t1,
t2,
self.con,
)
glfw.swap_buffers(self.window)
glfw.poll_events()
self._time_per_render = 0.9 * self._time_per_render + 0.1 * (
time.time() - render_start
)
# clear overlay
self._overlays.clear()
# clear markers
self._markers.clear()
if self._paused:
while self._paused:
update()
if self._advance_by_one_step:
self._advance_by_one_step = False
break
else:
self._loop_count += self.model.opt.timestep / (
self._time_per_render * self._run_speed
)
if self._render_every_frame:
self._loop_count = 1
while self._loop_count > 0:
update()
self._loop_count -= 1
================================================
FILE: bigym/const.py
================================================
"""A set of common constants."""
from __future__ import annotations
from enum import Enum, IntEnum
from pathlib import Path
import numpy as np
PACKAGE_PATH = Path(__file__).parent
ASSETS_PATH = PACKAGE_PATH / "envs" / "xmls"
PRESETS_PATH = PACKAGE_PATH / "envs" / "presets"
CACHE_PATH = Path.home() / ".bigym"
DEMO_RELEASES = "https://github.com/chernyadev/bigym_data/releases/download"
DEMO_VERSION = "0.9.0"
WORLD_MODEL = ASSETS_PATH / "world.xml"
class ActuatorGroup(IntEnum):
"""Enum class representing the actuator group."""
BASE = 0
LIMB = 1
GRIPPER = 2
class HandSide(Enum):
"""Enum class representing the hand side."""
LEFT = "Left"
RIGHT = "Right"
TOLERANCE_ANGULAR = np.deg2rad(2)
TOLERANCE_LINEAR = 1e-3
================================================
FILE: bigym/envs/__init__.py
================================================
"""Init."""
================================================
FILE: bigym/envs/cupboards.py
================================================
"""Cupboard interaction tasks."""
from abc import ABC
import numpy as np
from bigym.bigym_env import BiGymEnv
from bigym.const import PRESETS_PATH
from bigym.envs.props.cabintets import BaseCabinet, WallCabinet
TOLERANCE = 0.1
class _CupboardsInteractionEnv(BiGymEnv, ABC):
"""Base cupboards environment."""
RESET_ROBOT_POS = np.array([-0.2, 0, 0])
_PRESET_PATH = PRESETS_PATH / "counter_base_wall_3x1.yaml"
def _initialize_env(self):
self.cabinet_drawers = self._preset.get_props(BaseCabinet)[0]
self.cabinet_door_left = self._preset.get_props(BaseCabinet)[1]
self.cabinet_door_right = self._preset.get_props(BaseCabinet)[2]
self.cabinet_wall = self._preset.get_props(WallCabinet)[0]
self.all_cabinets = [
self.cabinet_drawers,
self.cabinet_door_left,
self.cabinet_door_right,
self.cabinet_wall,
]
class DrawerTopOpen(_CupboardsInteractionEnv):
"""Open top drawer of the cupboard task."""
def _success(self) -> bool:
return np.allclose(self.cabinet_drawers.get_state()[-1], 1, atol=TOLERANCE)
class DrawerTopClose(_CupboardsInteractionEnv):
"""Close top drawer of the cupboard task."""
def _success(self) -> bool:
return np.allclose(self.cabinet_drawers.get_state()[-1], 0, atol=TOLERANCE)
def _on_reset(self):
self.cabinet_drawers.set_state(np.array([0, 0, 1]))
class DrawersAllOpen(_CupboardsInteractionEnv):
"""Open all drawers of the cupboard task."""
def _success(self) -> bool:
return np.allclose(self.cabinet_drawers.get_state(), 1, atol=TOLERANCE)
class DrawersAllClose(_CupboardsInteractionEnv):
"""Close all drawers of the cupboard task."""
def _success(self) -> bool:
return np.allclose(self.cabinet_drawers.get_state(), 0, atol=TOLERANCE)
def _on_reset(self):
self.cabinet_drawers.set_state(np.array([1, 1, 1]))
class WallCupboardOpen(_CupboardsInteractionEnv):
"""Open doors of the wall cupboard task."""
def _success(self) -> bool:
return np.allclose(self.cabinet_wall.get_state(), 1, atol=TOLERANCE)
class WallCupboardClose(_CupboardsInteractionEnv):
"""Close doors of the wall cupboard task."""
def _success(self) -> bool:
return np.allclose(self.cabinet_wall.get_state(), 0, atol=TOLERANCE)
def _on_reset(self):
self.cabinet_wall.set_state(np.array([1, 1]))
class CupboardsOpenAll(_CupboardsInteractionEnv):
"""Open all doors/drawers of the kitchen counter task."""
def _success(self) -> bool:
for cabinet in self.all_cabinets:
if not np.allclose(cabinet.get_state(), 1, atol=TOLERANCE):
return False
return True
class CupboardsCloseAll(_CupboardsInteractionEnv):
"""Close all doors/drawers of the kitchen counter task."""
def _success(self) -> bool:
for cabinet in self.all_cabinets:
if not np.allclose(cabinet.get_state(), 0, atol=TOLERANCE):
return False
return True
def _on_reset(self):
for cabinet in self.all_cabinets:
cabinet.set_state(np.ones_like(cabinet.get_state()))
================================================
FILE: bigym/envs/dishwasher.py
================================================
"""Dishwasher interaction tasks."""
from abc import ABC
import numpy as np
from bigym.bigym_env import BiGymEnv
from bigym.const import PRESETS_PATH
from bigym.envs.props.dishwasher import Dishwasher
class _DishwasherEnv(BiGymEnv, ABC):
"""Base dishwasher environment."""
RESET_ROBOT_POS = np.array([0, -0.8, 0])
_PRESET_PATH = PRESETS_PATH / "dishwasher.yaml"
_TOLERANCE = 0.05
def _initialize_env(self):
self.dishwasher = self._preset.get_props(Dishwasher)[0]
class DishwasherOpen(_DishwasherEnv):
"""Open the dishwasher door and pull out all trays."""
def _success(self) -> bool:
return np.allclose(self.dishwasher.get_state(), 1, atol=self._TOLERANCE)
def _on_reset(self):
self.dishwasher.set_state(door=0, bottom_tray=0, middle_tray=0)
class DishwasherClose(_DishwasherEnv):
"""Push back all trays and close the door of the dishwasher."""
def _success(self) -> bool:
return np.allclose(self.dishwasher.get_state(), 0, atol=self._TOLERANCE)
def _on_reset(self):
self.dishwasher.set_state(door=1, bottom_tray=1, middle_tray=1)
class DishwasherCloseTrays(DishwasherClose):
"""Push the dishwasher’s trays back with the door initially open."""
def _success(self) -> bool:
return np.allclose(self.dishwasher.get_state()[1:], 0, atol=self._TOLERANCE)
class DishwasherOpenTrays(DishwasherClose):
"""Pull out the dishwasher’s trays with the door initially open."""
def _success(self) -> bool:
return np.allclose(self.dishwasher.get_state()[1:], 1, atol=self._TOLERANCE)
def _on_reset(self):
self.dishwasher.set_state(door=1, bottom_tray=0, middle_tray=0)
================================================
FILE: bigym/envs/dishwasher_cups.py
================================================
"""Load/unload cups to/from dishwasher."""
from abc import ABC
import numpy as np
from pyquaternion import Quaternion
from bigym.bigym_env import BiGymEnv
from bigym.const import PRESETS_PATH
from bigym.envs.props.cabintets import BaseCabinet, WallCabinet
from bigym.envs.props.dishwasher import Dishwasher
from bigym.envs.props.kitchenware import Mug
from bigym.utils.env_utils import get_random_sites
class _DishwasherCupsEnv(BiGymEnv, ABC):
"""Base cups environment."""
RESET_ROBOT_POS = np.array([0, -0.6, 0])
_PRESET_PATH = PRESETS_PATH / "counter_dishwasher.yaml"
_CUPS_COUNT = 2
def _initialize_env(self):
self.dishwasher = self._preset.get_props(Dishwasher)[0]
self.cabinets = self._preset.get_props(BaseCabinet)
self.cups = [Mug(self._mojo) for _ in range(self._CUPS_COUNT)]
def _fail(self) -> bool:
if super()._fail():
return True
for cup in self.cups:
if cup.is_colliding(self.floor):
return True
return False
def _on_reset(self):
self.dishwasher.set_state(door=1, bottom_tray=0, middle_tray=1)
class DishwasherUnloadCups(_DishwasherCupsEnv):
"""Unload cups from dishwasher task."""
_SITES_STEP = 3
_SITES_SLICE = 3
_CUPS_ROT_X = np.deg2rad(180)
_CUPS_ROT_Z = np.deg2rad(90)
_CUPS_ROT_BOUNDS = np.deg2rad(5)
_CUPS_POS = np.array([0, -0.05, 0.05])
_CUPS_STEP = np.array([0.115, 0, 0])
def _success(self) -> bool:
for cup in self.cups:
if not any([cup.is_colliding(cabinet) for cabinet in self.cabinets]):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(cup, side):
return False
return True
def _on_reset(self):
super()._on_reset()
sites = self.dishwasher.tray_middle.site_sets[0]
sites = get_random_sites(
sites, len(self.cups), self._SITES_STEP, self._SITES_SLICE
)
for site, cup in zip(sites, self.cups):
quat = Quaternion(axis=[1, 0, 0], angle=self._CUPS_ROT_X)
angle = np.random.uniform(-self._CUPS_ROT_BOUNDS, self._CUPS_ROT_BOUNDS)
quat *= Quaternion(axis=[0, 0, 1], angle=self._CUPS_ROT_Z + angle)
cup.body.set_quaternion(quat.elements, True)
pos = site.get_position()
pos += self._CUPS_POS
cup.body.set_position(pos, True)
class DishwasherUnloadCupsLong(DishwasherUnloadCups):
"""Unload cup from dishwasher in wall cabinet task."""
_PRESET_PATH = PRESETS_PATH / "counter_dishwasher_wall_cabinet.yaml"
_CUPS_COUNT = 1
_SITES_SLICE = 2
_TOLERANCE = 0.1
def _initialize_env(self):
super()._initialize_env()
self.wall_cabinet = self._preset.get_props(WallCabinet)[0]
def _success(self) -> bool:
if not np.allclose(self.dishwasher.get_state(), 0, atol=self._TOLERANCE):
return False
if not np.allclose(self.wall_cabinet.get_state(), 0, atol=self._TOLERANCE):
return False
for cup in self.cups:
if not cup.is_colliding(self.wall_cabinet.shelf_bottom):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(cup, side):
return False
return True
class DishwasherLoadCups(_DishwasherCupsEnv):
"""Load cups to dishwasher task."""
_CUPS_POS = np.array([0.6, -0.6, 1])
_CUPS_POS_STEP = np.array([0, 0.15, 0])
_CUPS_POS_BOUNDS = np.array([0.05, 0.02, 0])
_CUPS_ROT_X = np.deg2rad(180)
_CUPS_ROT_Z = np.deg2rad(180)
_CUPS_ROT_BOUNDS = np.deg2rad(30)
def _success(self) -> bool:
for cup in self.cups:
if not cup.is_colliding(self.dishwasher.tray_middle.colliders):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(cup, side):
return False
return True
def _on_reset(self):
super()._on_reset()
for i, cup in enumerate(self.cups):
quat = Quaternion(axis=[1, 0, 0], angle=self._CUPS_ROT_X)
angle = np.random.uniform(-self._CUPS_ROT_BOUNDS, self._CUPS_ROT_BOUNDS)
quat *= Quaternion(axis=[0, 0, 1], angle=self._CUPS_ROT_Z + angle)
cup.body.set_quaternion(quat.elements, True)
pos = self._CUPS_POS + i * self._CUPS_POS_STEP
pos += np.random.uniform(-self._CUPS_POS_BOUNDS, self._CUPS_POS_BOUNDS)
cup.body.set_position(pos, True)
================================================
FILE: bigym/envs/dishwasher_cutlery.py
================================================
"""Load/unload cutlery to/from dishwasher."""
from abc import ABC
import numpy as np
from pyquaternion import Quaternion
from bigym.bigym_env import BiGymEnv
from bigym.const import PRESETS_PATH
from bigym.envs.props.cabintets import BaseCabinet
from bigym.envs.props.cutlery import Fork, Knife
from bigym.envs.props.dishwasher import Dishwasher
from bigym.envs.props.holders import CutleryTray
from bigym.envs.props.kitchenware import Mug
from bigym.robots.configs.h1 import H1FineManipulation
from bigym.utils.env_utils import get_random_sites
class _DishwasherCutleryEnv(BiGymEnv, ABC):
"""Base cutlery environment."""
DEFAULT_ROBOT = H1FineManipulation
_PRESET_PATH = PRESETS_PATH / "counter_dishwasher.yaml"
_CUTLERY = [Knife, Fork]
RESET_ROBOT_POS = np.array([0, -0.6, 0])
def _initialize_env(self):
self.dishwasher = self._preset.get_props(Dishwasher)[0]
self.cutlery = [item_cls(self._mojo) for item_cls in self._CUTLERY]
def _fail(self) -> bool:
if super()._fail():
return True
for item in self.cutlery:
if item.is_colliding(self.floor):
return True
return False
def _on_reset(self):
self.dishwasher.set_state(door=1, bottom_tray=1, middle_tray=0)
class _DishwasherUnloadCutleryEnv(_DishwasherCutleryEnv):
"""Base unload cutlery from dishwasher task."""
_SITES_SLICE = -2
_CUTLERY_OFFSET_POS = np.array([0, 0, 0.1])
_CUTLERY_BOUNDS_ANGLE = np.deg2rad(30)
_CUTLERY_SPAWN_ROT = Quaternion(axis=[1, 0, 0], degrees=90)
def _on_reset(self):
super()._on_reset()
sites = self.dishwasher.basket.site_sets[0]
sites = get_random_sites(sites, len(self.cutlery), segment=self._SITES_SLICE)
for site, item in zip(sites, self.cutlery):
item_pos = site.get_position() + self._CUTLERY_OFFSET_POS
angle = np.random.uniform(
-self._CUTLERY_BOUNDS_ANGLE, self._CUTLERY_BOUNDS_ANGLE
)
item_quat = self._CUTLERY_SPAWN_ROT * Quaternion(
axis=[0, 1, 0], angle=angle
)
item.body.set_quaternion(item_quat.elements, True)
item.body.set_position(item_pos, True)
class DishwasherUnloadCutlery(_DishwasherUnloadCutleryEnv):
"""Unload cutlery from dishwasher task."""
_TRAY_POS = np.array([0.65, -0.6, 0.86])
_TRAY_BOUNDS = np.array([0.05, 0.05, 0])
_TRAY_ROT = np.array([0, 0, -np.pi / 2])
def _initialize_env(self):
super()._initialize_env()
self.tray = CutleryTray(self._mojo)
def _success(self) -> bool:
for item in self.cutlery:
if not item.is_colliding(self.tray):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(item, side):
return False
return True
def _on_reset(self):
super()._on_reset()
offset = np.random.uniform(-self._TRAY_BOUNDS, self._TRAY_BOUNDS)
self.tray.body.set_position(self._TRAY_POS + offset)
self.tray.body.set_euler(self._TRAY_ROT)
class DishwasherUnloadCutleryLong(_DishwasherUnloadCutleryEnv):
"""Unload cutlery from dishwasher to drawer task."""
_PRESET_PATH = PRESETS_PATH / "counter_dishwasher_cutlery_cabinet.yaml"
_CUTLERY = [Fork]
_TOLERANCE = 0.1
def _initialize_env(self):
super()._initialize_env()
self.cutlery_cabinet = self._preset.get_props(BaseCabinet)[-1]
self.tray = self._preset.get_props(CutleryTray)[0]
def _success(self) -> bool:
if not np.allclose(self.dishwasher.get_state(), 0, atol=self._TOLERANCE):
return False
if not np.allclose(self.cutlery_cabinet.get_state(), 0, atol=self._TOLERANCE):
return False
for item in self.cutlery:
if not item.is_colliding(self.tray):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(item, side):
return False
return True
class DishwasherLoadCutlery(_DishwasherCutleryEnv):
"""Load cutlery to dishwasher task."""
_MUG_POS = np.array([0.65, -0.6, 0.86])
_MUG_BOUNDS = np.array([0.05, 0.05, 0])
_MUG_BOUNDS_ANGLE = np.deg2rad(90)
_BASKET_OFFSET_POS = np.array([0, 0, 0.15])
_CUTLERY_SPAWN_ROT = Quaternion(axis=[1, 0, 0], degrees=90)
_CUTLERY_OFFSET_ANGLE = np.deg2rad(90)
_CUTLERY_OFFSET_ANGLE_RANGE = np.deg2rad(5)
_CUTLERY_SPAWN_OFFSET = 0.02
def _initialize_env(self):
super()._initialize_env()
self.mug = Mug(self._mojo, False)
def _success(self) -> bool:
for item in self.cutlery:
if not item.is_colliding(self.dishwasher.basket.colliders):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(item, side):
return False
return True
def _on_reset(self):
super()._on_reset()
mug_angle = np.random.uniform(-self._MUG_BOUNDS_ANGLE, self._MUG_BOUNDS_ANGLE)
self.mug.body.set_euler(np.array([0, 0, mug_angle]))
offset = np.random.uniform(-self._MUG_BOUNDS, self._MUG_BOUNDS)
mug_pos = self._MUG_POS + offset
self.mug.body.set_position(mug_pos, True)
for i, item in enumerate(self.cutlery):
item.body.set_quaternion(self._CUTLERY_SPAWN_ROT.elements, True)
offset_angle = self._CUTLERY_OFFSET_ANGLE * i
offset_angle += np.random.uniform(
-self._CUTLERY_OFFSET_ANGLE_RANGE, self._CUTLERY_OFFSET_ANGLE_RANGE
)
item_offset = np.array([np.cos(offset_angle), np.sin(offset_angle), 0])
item_offset *= self._CUTLERY_SPAWN_OFFSET
item_pos = mug_pos.copy() + self._BASKET_OFFSET_POS + item_offset
item.body.set_position(item_pos, True)
================================================
FILE: bigym/envs/dishwasher_plates.py
================================================
"""Load/unload plates to/from dishwasher."""
from abc import ABC
import numpy as np
import quaternion
from pyquaternion import Quaternion
from bigym.bigym_env import BiGymEnv
from bigym.const import PRESETS_PATH
from bigym.envs.props.holders import DishDrainer
from bigym.envs.props.dishwasher import Dishwasher
from bigym.envs.props.cabintets import WallCabinet
from bigym.envs.props.kitchenware import Plate
from bigym.utils.env_utils import get_random_sites
class _DishwasherPlatesEnv(BiGymEnv, ABC):
"""Base plates environment."""
RESET_ROBOT_POS = np.array([0, -0.6, 0])
_PRESET_PATH = PRESETS_PATH / "counter_dishwasher.yaml"
_RACK_POSITION = np.array([0.6, -0.6, 0.86])
_RACK_BOUNDS = np.array([0.05, 0.05, 0])
_PLATES_COUNT = 2
_PLATE_ROTATION = quaternion.from_euler_angles(np.pi / 2, np.pi / 2, 0)
_PLATE_OFFSET_POS = np.array([0, -0.01, 0.05])
_SITES_STEP = 2
_SITES_SLICE = 4
_TOLERANCE = np.deg2rad(20)
def _initialize_env(self):
self.dishwasher = self._preset.get_props(Dishwasher)[0]
self.drainer: DishDrainer = DishDrainer(self._mojo)
self.plates: list[Plate] = []
for _ in range(self._PLATES_COUNT):
self.plates.append(Plate(self._mojo))
def _fail(self) -> bool:
if super()._fail():
return True
for plate in self.plates:
if plate.is_colliding(self.floor):
return True
return False
def _on_reset(self):
self.dishwasher.set_state(door=1, bottom_tray=1, middle_tray=0)
offset = np.random.uniform(-self._RACK_BOUNDS, self._RACK_BOUNDS)
self.drainer.body.set_position(self._RACK_POSITION + offset)
class DishwasherUnloadPlates(_DishwasherPlatesEnv):
"""Unload plates from dishwasher task."""
def _success(self) -> bool:
for plate in self.plates:
if not plate.is_colliding(self.drainer):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(plate, side):
return False
return True
def _on_reset(self):
super()._on_reset()
sites = self.dishwasher.tray_bottom.site_sets[0]
sites = get_random_sites(
sites, len(self.plates), self._SITES_STEP, self._SITES_SLICE
)
for plate, site in zip(self.plates, sites):
plate.body.set_quaternion(quaternion.as_float_array(self._PLATE_ROTATION))
plate.body.set_position(site.get_position() + self._PLATE_OFFSET_POS)
class DishwasherUnloadPlatesLong(DishwasherUnloadPlates):
"""Unload plate from dishwasher in wall cabinet task."""
_PRESET_PATH = PRESETS_PATH / "counter_dishwasher_wall_cabinet.yaml"
_PLATES_COUNT = 1
_RACK_POSITION = np.array([0.8, -0.6, 1.474])
_RACK_BOUNDS = np.array([0.01, 0.05, 0])
_TOLERANCE = 0.1
def _initialize_env(self):
super()._initialize_env()
self.wall_cabinet = self._preset.get_props(WallCabinet)[0]
def _success(self) -> bool:
if not np.allclose(self.dishwasher.get_state(), 0, atol=self._TOLERANCE):
return False
if not np.allclose(self.wall_cabinet.get_state(), 0, atol=self._TOLERANCE):
return False
return super()._success()
class DishwasherLoadPlates(_DishwasherPlatesEnv):
"""Load plates to dishwasher task."""
def _success(self) -> bool:
up = np.array([0, 0, 1])
right = np.array([0, -1, 0])
for plate in self.plates:
plate_up = Quaternion(plate.body.get_quaternion()).rotate(up)
angle_to_right = np.arccos(np.clip(np.dot(plate_up, right), -1.0, 1.0))
angle_to_left = np.arccos(np.clip(np.dot(plate_up, -right), -1.0, 1.0))
if not (
angle_to_right <= self._TOLERANCE or angle_to_left <= self._TOLERANCE
):
return False
if not plate.is_colliding(self.dishwasher.tray_bottom.colliders):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(plate, side):
return False
return True
def _on_reset(self):
super()._on_reset()
sites = self.drainer.sites
sites = get_random_sites(
sites, len(self.plates), self._SITES_STEP, self._SITES_SLICE
)
for plate, site in zip(self.plates, sites):
plate.body.set_quaternion(quaternion.as_float_array(self._PLATE_ROTATION))
plate.body.set_position(site.get_position() + self._PLATE_OFFSET_POS)
================================================
FILE: bigym/envs/groceries.py
================================================
"""Groceries tasks."""
import numpy as np
from bigym.bigym_env import BiGymEnv
from bigym.const import PRESETS_PATH
from bigym.envs.props.cabintets import BaseCabinet, WallCabinet, OpenShelf
from bigym.envs.props.items import Wine, Beer, Soap, Cereals, Ketchup, Mustard, Soda
from bigym.envs.props.prop import Prop
from bigym.utils.env_utils import get_random_points_on_plane
class GroceriesStoreLower(BiGymEnv):
"""Put groceries to lower cabinets tasks."""
_PRESET_PATH = PRESETS_PATH / "counter_base_2.yaml"
_PROP_TYPES = [Wine, Soap, Beer, Cereals, Ketchup, Mustard, Soda]
_PROPS_PER_CATEGORY = 1
_PROPS_COUNT = 4
_PROPS_POS = np.array([0.7, -0.3, 0.9])
_PROPS_STEP = 0.2
_PROPS_POS_EXTENTS = np.array([0.1, 0.5])
_PROPS_POS_BOUNDS = np.array([0.1, 0.05, 0])
_PROPS_ROT_BOUNDS = np.deg2rad([0, 0, 180])
def _initialize_env(self):
self.cabinet_1 = self._preset.get_props(BaseCabinet)[0]
self.cabinet_2 = self._preset.get_props(BaseCabinet)[1]
self.props: list[Prop] = []
self.selected_props: list[Prop] = []
for prop_type in self._PROP_TYPES:
self.props.extend(
[prop_type(self._mojo) for _ in range(self._PROPS_PER_CATEGORY)]
)
def _on_reset(self):
for prop in self.props:
prop.disable()
self.selected_props = np.random.choice(
np.array(self.props), size=self._PROPS_COUNT, replace=False
)
points = get_random_points_on_plane(
len(self.selected_props),
self._PROPS_POS,
self._PROPS_POS_EXTENTS,
self._PROPS_STEP,
)
for prop, point in zip(self.selected_props, points):
prop.enable()
prop.set_pose(
point,
position_bounds=self._PROPS_POS_BOUNDS,
rotation_bounds=self._PROPS_ROT_BOUNDS,
)
def _success(self) -> bool:
for prop in self.selected_props:
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(prop, side):
return False
if not (
prop.is_colliding(self.cabinet_1.shelf)
or prop.is_colliding(self.cabinet_1.shelf_bottom)
or prop.is_colliding(self.cabinet_2.shelf_bottom)
):
return False
return True
class GroceriesStoreUpper(GroceriesStoreLower):
"""Put groceries to upper cabinets tasks."""
_PRESET_PATH = PRESETS_PATH / "counter_base_wall_2x2.yaml"
def _initialize_env(self):
super()._initialize_env()
self.cabinet_wall = self._preset.get_props(WallCabinet)[0]
self.shelf = self._preset.get_props(OpenShelf)[0]
def _success(self) -> bool:
for prop in self.selected_props:
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(prop, side):
return False
if not (
prop.is_colliding(self.cabinet_wall.shelf)
or prop.is_colliding(self.cabinet_wall.shelf_bottom)
or prop.is_colliding(self.shelf.shelf)
):
return False
return True
================================================
FILE: bigym/envs/manipulation.py
================================================
"""Manipulation tasks."""
from abc import ABC
import numpy as np
from mojo.elements import Body, Geom
from mojo.elements.consts import GeomType
from pyquaternion import Quaternion
from bigym.bigym_env import BiGymEnv
from bigym.const import PRESETS_PATH
from bigym.envs.props.cabintets import BaseCabinet
from bigym.envs.props.cutlery import Spoon
from bigym.envs.props.items import Cube
from bigym.envs.props.kitchenware import Mug
from bigym.robots.configs.h1 import H1FineManipulation
from bigym.utils.env_utils import get_random_points_on_plane
class _ManipulationEnv(BiGymEnv, ABC):
"""Base manipulation environment."""
_PRESET_PATH = PRESETS_PATH / "cabinet.yaml"
def _initialize_env(self):
self.cabinet = self._preset.get_props(BaseCabinet)[0]
class FlipCup(_ManipulationEnv):
"""Flip cup upside-up task."""
_CUP_POS = np.array([0.8, 0, 1])
_CUP_ROT_X = np.deg2rad(180)
_CUP_ROT_Z = np.deg2rad(180)
_CUP_STEP = 0.1
_CUP_POS_EXTENTS = np.array([0.1, 0.25])
_CUP_POS_BOUNDS = np.array([0.03, 0.03, 0])
_CUP_ROT_BOUNDS = np.deg2rad(30)
_TOLERANCE = np.deg2rad(5)
def _initialize_env(self):
super()._initialize_env()
self.cup = Mug(self._mojo)
def _success(self) -> bool:
up = np.array([0, 0, 1])
cup_up = Quaternion(self.cup.body.get_quaternion()).rotate(up)
angle_to_up = np.arccos(np.clip(np.dot(cup_up, up), -1.0, 1.0))
if angle_to_up > self._TOLERANCE:
return False
if not self.cup.is_colliding(self.cabinet.counter):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(self.cup, side):
return False
return True
def _on_reset(self):
spawn_point = get_random_points_on_plane(
1,
self._CUP_POS,
self._CUP_POS_EXTENTS,
self._CUP_STEP,
self._CUP_POS_BOUNDS,
)[0]
self.cup.body.set_position(spawn_point, True)
quat = Quaternion(axis=[1, 0, 0], angle=self._CUP_ROT_X)
angle = np.random.uniform(-self._CUP_ROT_BOUNDS, self._CUP_ROT_BOUNDS)
quat *= Quaternion(axis=[0, 0, 1], angle=self._CUP_ROT_Z + angle)
self.cup.body.set_quaternion(quat.elements, True)
class FlipCutlery(_ManipulationEnv):
"""Flip cutlery item task."""
DEFAULT_ROBOT = H1FineManipulation
_CUP_POS = np.array([0.8, 0, 0.86])
_CUP_ROT_Z = np.deg2rad(180)
_CUP_STEP = 0.1
_CUP_POS_EXTENTS = np.array([0.1, 0.25])
_CUP_POS_BOUNDS = np.array([0.03, 0.03, 0])
_CUP_ROT_BOUNDS = np.deg2rad(180)
_SPOON_OFFSET = np.array([0, 0, 0.15])
_SPOON_QUAT = Quaternion(axis=[1, 0, 0], degrees=90)
_TOLERANCE = np.deg2rad(50)
def _initialize_env(self):
super()._initialize_env()
self.cup = Mug(self._mojo, kinematic=False)
self.spoon = Spoon(self._mojo)
def _success(self) -> bool:
down = np.array([0, 0, -1])
fwd = np.array([0, 1, 0])
spoon_fwd = Quaternion(self.spoon.body.get_quaternion()).rotate(fwd)
angle_to_up = np.arccos(np.clip(np.dot(spoon_fwd, down), -1.0, 1.0))
if angle_to_up > self._TOLERANCE:
return False
if not self.spoon.is_colliding(self.cup):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(self.cup, side):
return False
return True
def _on_reset(self):
spawn_point = get_random_points_on_plane(
1,
self._CUP_POS,
self._CUP_POS_EXTENTS,
self._CUP_STEP,
self._CUP_POS_BOUNDS,
)[0]
self.cup.body.set_position(spawn_point)
angle = np.random.uniform(-self._CUP_ROT_BOUNDS, self._CUP_ROT_BOUNDS)
quat = Quaternion(axis=[0, 0, 1], angle=self._CUP_ROT_Z + angle)
self.cup.body.set_quaternion(quat.elements)
self.spoon.body.set_position(spawn_point + self._SPOON_OFFSET, True)
self.spoon.body.set_quaternion(self._SPOON_QUAT.elements, True)
class StackBlocks(BiGymEnv):
"""Stack blocks in the correct area of the table."""
_PRESET_PATH = PRESETS_PATH / "stack_blocks.yaml"
_NUM_BLOCKS = 3
_BLOCKS_POS = np.array([0.7, 0, 1])
_BLOCKS_POS_EXTENTS = np.array([0.2, 0.5])
_BLOCKS_STEP = 0.15
_BLOCKS_POS_BOUNDS = np.array([0.05, 0.05, 0])
_BLOCKS_ROT_BOUNDS = np.deg2rad([0, 0, 180])
_TARGET_SIZE = np.array([0.05, 0.05, 0.001])
_TARGET_COLOR = np.array([0.3, 0.8, 0.3, 1.0])
_TARGET_POS = np.array([1.4, 0, 0.95])
_TARGET_POS_BOUNDS = np.array([0.05, 0.2, 0.0])
def _initialize_env(self):
self.blocks = [Cube(self._mojo) for _ in range(self._NUM_BLOCKS)]
self.target: Body = Body.create(self._mojo)
self.target_collider = Geom.create(
self._mojo,
parent=self.target,
geom_type=GeomType.BOX,
size=self._TARGET_SIZE,
color=self._TARGET_COLOR,
)
def _on_reset(self):
points = get_random_points_on_plane(
len(self.blocks),
self._BLOCKS_POS,
self._BLOCKS_POS_EXTENTS,
self._BLOCKS_STEP,
)
for block, point in zip(self.blocks, points):
block.set_pose(
point,
position_bounds=self._BLOCKS_POS_BOUNDS,
rotation_bounds=self._BLOCKS_ROT_BOUNDS,
)
offset = np.random.uniform(-self._TARGET_POS_BOUNDS, self._TARGET_POS_BOUNDS)
self.target.set_position(self._TARGET_POS + offset)
def _success(self) -> bool:
blocks_sorted = sorted(self.blocks, key=lambda b: b.body.get_position()[2])
if not blocks_sorted[0].is_colliding(self.target_collider):
return False
if not blocks_sorted[1].is_colliding(blocks_sorted[0]):
return False
if not blocks_sorted[2].is_colliding(blocks_sorted[1]):
return False
for block in self.blocks:
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(block, side):
return False
return True
def _fail(self) -> bool:
if super()._fail():
return True
for block in self.blocks:
if block.is_colliding(self.floor):
return True
return False
================================================
FILE: bigym/envs/move_plates.py
================================================
"""Set of plate moving tasks."""
from abc import ABC
import numpy as np
from gymnasium import spaces
from pyquaternion import Quaternion
from bigym.bigym_env import BiGymEnv
from bigym.const import PRESETS_PATH
from bigym.envs.props.holders import DishDrainer
from bigym.envs.props.kitchenware import Plate
from bigym.envs.props.tables import Table
from bigym.utils.physics_utils import distance
RACK_BOUNDS = np.array([0.05, 0.05, 0])
RACK_POSITION_LEFT = np.array([0.7, 0.3, 0.95])
RACK_POSITION_RIGHT = np.array([0.7, -0.3, 0.95])
PLATE_OFFSET_POS = np.array([0, 0.01, 0])
PLATE_OFFSET_ROT = Quaternion(axis=[1, 0, 0], degrees=-5).elements
class _MovePlatesEnv(BiGymEnv, ABC):
"""Base plates environment."""
_PRESET_PATH = PRESETS_PATH / "move_plates.yaml"
_SUCCESSFUL_DIST = 0.05
_SUCCESS_ROT = np.deg2rad(20)
_PLATES_COUNT = 1
def _initialize_env(self):
self.table = self._preset.get_props(Table)[0]
self.rack_start = self._preset.get_props(DishDrainer)[0]
self.rack_target = self._preset.get_props(DishDrainer)[1]
self.plates = [Plate(self._mojo) for _ in range(self._PLATES_COUNT)]
def _success(self) -> bool:
up = np.array([0, 0, 1])
right = np.array([0, -1, 0])
for plate in self.plates:
if np.all(
[
distance(plate.body, site) > self._SUCCESSFUL_DIST
for site in self.rack_target.sites
]
):
return False
plate_up = Quaternion(plate.body.get_quaternion()).rotate(up)
angle = np.arccos(np.clip(np.dot(plate_up, right), -1.0, 1.0))
if angle > self._SUCCESS_ROT:
return False
if not plate.is_colliding(self.rack_target):
return False
if plate.is_colliding(self.table):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(plate, side):
return False
return True
def _fail(self) -> bool:
if super()._fail():
return True
for plate in self.plates:
if plate.is_colliding(self.floor):
return True
return False
def _on_reset(self):
offset = np.random.uniform(-RACK_BOUNDS, RACK_BOUNDS)
self.rack_start.body.set_position(RACK_POSITION_LEFT + offset)
offset = np.random.uniform(-RACK_BOUNDS, RACK_BOUNDS)
self.rack_target.body.set_position(RACK_POSITION_RIGHT + offset)
sites = np.array(self.rack_start.sites)
sites = np.random.choice(sites, size=len(self.plates), replace=False)
for site, plate in zip(sites, self.plates):
plate.body.set_position(site.get_position() + PLATE_OFFSET_POS, True)
quat = Quaternion(site.get_quaternion())
quat *= PLATE_OFFSET_ROT
plate.body.set_quaternion(quat.elements, True)
class MovePlate(_MovePlatesEnv):
"""Move one plate from one rack to another."""
def _get_task_privileged_obs_space(self):
return {
"rack_pose": spaces.Box(
low=-np.inf, high=np.inf, shape=(7,), dtype=np.float32
),
"plate_pose": spaces.Box(
low=-np.inf, high=np.inf, shape=(3,), dtype=np.float32
),
}
def _get_task_privileged_obs(self):
return {
"rack_pose": np.array(self.rack_target.get_pose(), np.float32).flatten(),
"plate_pose": np.array(self.plates[0].get_pose(), np.float32).flatten(),
}
class MoveTwoPlates(_MovePlatesEnv):
"""Move two plates from one rack to another."""
_PLATES_COUNT = 2
def _get_task_privileged_obs_space(self):
return {}
def _get_task_privileged_obs(self):
return {}
================================================
FILE: bigym/envs/pick_and_place.py
================================================
"""Pick and place tasks."""
import numpy as np
from pyquaternion import Quaternion
from bigym.bigym_env import BiGymEnv
from bigym.const import PRESETS_PATH
from bigym.envs.props.cabintets import BaseCabinet, WallCabinet
from bigym.envs.props.cutlery import Spatula
from bigym.envs.props.items import Box, Sandwich
from bigym.envs.props.prop import Prop
from bigym.envs.props.kitchenware import Mug, Saucepan, Pan, ChoppingBoard
from bigym.robots.configs.h1 import H1FineManipulation
from bigym.utils.env_utils import get_random_points_on_plane
class PutCups(BiGymEnv):
"""Put cups in the wall cabinet."""
_PRESET_PATH = PRESETS_PATH / "counter_base_wall_1x1.yaml"
_CUPS_COUNT = 2
_CUPS_POS = np.array([0.8, 0, 1])
_CUPS_ROT = np.deg2rad(180)
_CUPS_STEP = 0.15
_CUPS_POS_EXTENTS = np.array([0.1, 0.25])
_CUPS_POS_BOUNDS = np.array([0.03, 0.03, 0])
_CUPS_ROT_BOUNDS = np.deg2rad(30)
def _initialize_env(self):
self.cabinet_base = self._preset.get_props(BaseCabinet)[0]
self.cabinet_wall = self._preset.get_props(WallCabinet)[0]
self.cups = [Mug(self._mojo) for _ in range(self._CUPS_COUNT)]
def _success(self) -> bool:
for cup in self.cups:
if not cup.is_colliding(self.cabinet_wall.shelf_bottom):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(cup, side):
return False
return True
def _on_reset(self):
points = get_random_points_on_plane(
len(self.cups),
self._CUPS_POS,
self._CUPS_POS_EXTENTS,
self._CUPS_STEP,
self._CUPS_POS_BOUNDS,
)
for cup, point in zip(self.cups, points):
cup.body.set_position(point)
angle = np.random.uniform(-self._CUPS_ROT_BOUNDS, self._CUPS_ROT_BOUNDS)
cup.body.set_quaternion(
Quaternion(axis=[0, 0, 1], angle=self._CUPS_ROT + angle).elements
)
class TakeCups(PutCups):
"""Take cups from the wall cupboard."""
_CUPS_POS = np.array([1.05, 0, 1.5])
def _success(self) -> bool:
for cup in self.cups:
if not cup.is_colliding(self.cabinet_base.counter):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(cup, side):
return False
return True
class StoreBox(BiGymEnv):
"""Put box in the cupboard task."""
_PRESET_PATH = PRESETS_PATH / "cabinet_door.yaml"
_BOX_POS = np.array([0.8, 0, 1])
_BOX_POS_BOUNDS = np.array([0.03, 0.03, 0])
_BOX_ROT_BOUNDS = np.deg2rad(180)
def _initialize_env(self):
self.cabinet_base = self._preset.get_props(BaseCabinet)[0]
self.box = Box(self._mojo, True)
def _on_reset(self):
offset = np.random.uniform(-self._BOX_POS_BOUNDS, self._BOX_POS_BOUNDS)
self.box.body.set_position(self._BOX_POS + offset, True)
angle = np.random.uniform(-self._BOX_ROT_BOUNDS, self._BOX_ROT_BOUNDS)
self.box.body.set_quaternion(Quaternion(axis=[0, 0, 1], angle=angle).elements)
def _success(self) -> bool:
if not self.box.is_colliding(self.cabinet_base.shelf):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(self.box, side):
return False
return True
class PickBox(StoreBox):
"""Pick up box from and place it on the counter task."""
_BOX_POS = np.array([0.8, -1, 0.2])
_BOX_QUAT = Quaternion(axis=[0, 1, 0], degrees=90)
def _success(self) -> bool:
if not self.box.is_colliding(self.cabinet_base.counter):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(self.box, side):
return False
return True
def _on_reset(self):
offset = np.random.uniform(-self._BOX_POS_BOUNDS, self._BOX_POS_BOUNDS)
self.box.body.set_position(self._BOX_POS + offset, True)
angle = np.random.uniform(-self._BOX_ROT_BOUNDS, self._BOX_ROT_BOUNDS)
quat = self._BOX_QUAT
quat *= Quaternion(axis=[1, 0, 0], angle=angle)
self.box.body.set_quaternion(quat.elements)
class SaucepanToHob(BiGymEnv):
"""Take saucepan from cabinet and place it to hob."""
_PRESET_PATH = PRESETS_PATH / "cabinet_hob.yaml"
_SAUCEPAN_POS = np.array([0.85, 0.1, 0.5])
_SAUCEPAN_QUAT = Quaternion(axis=[0, 0, 1], degrees=90)
_SAUCEPAN_POS_BOUNDS = np.array([0.05, 0.05, 0])
_SAUCEPAN_ROT_BOUNDS = np.deg2rad([0, 0, 20])
def _initialize_env(self):
self.cabinet_base = self._preset.get_props(BaseCabinet)[0]
self.saucepan = Saucepan(self._mojo)
def _success(self) -> bool:
if not self.saucepan.is_colliding(self.cabinet_base.hob):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(self.saucepan, side):
return False
return True
def _on_reset(self):
self.saucepan.set_pose(
self._SAUCEPAN_POS,
self._SAUCEPAN_QUAT.elements,
self._SAUCEPAN_POS_BOUNDS,
self._SAUCEPAN_ROT_BOUNDS,
)
class StoreKitchenware(BiGymEnv):
"""Put all kitchenware to cupboard."""
_PRESET_PATH = PRESETS_PATH / "cabinet_hob.yaml"
_ITEMS = [Saucepan, Pan]
_ITEMS_QUAT = Quaternion(axis=[0, 0, 1], degrees=15)
_ITEMS_POS_BOUNDS = np.array([0.02, 0.02, 0])
_ITEMS_ROT_BOUNDS = np.deg2rad([0, 0, 30])
def _initialize_env(self):
self.cabinet_base = self._preset.get_props(BaseCabinet)[0]
self.items: list[Prop] = [item(self._mojo) for item in self._ITEMS]
def _success(self) -> bool:
for item in self.items:
if not item.is_colliding(self.cabinet_base.shelf):
return False
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(item, side):
return False
return True
def _on_reset(self):
sites = [self.cabinet_base.sites[0], self.cabinet_base.sites[2]]
np.random.shuffle(sites)
for item, site in zip(self.items, sites):
item.set_pose(
site.get_position(),
self._ITEMS_QUAT.elements,
self._ITEMS_POS_BOUNDS,
self._ITEMS_ROT_BOUNDS,
)
class ToastSandwich(BiGymEnv):
"""Move sandwich on the frying pan."""
DEFAULT_ROBOT = H1FineManipulation
_PRESET_PATH = PRESETS_PATH / "counter_base_2_hob.yaml"
_PAN_QUAT = Quaternion(axis=[0, 0, 1], degrees=-90)
_PAN_POS_BOUNDS = np.array([0.02, 0.02, 0])
_PAN_ROT_BOUNDS = np.deg2rad([0, 0, 30])
_SPATULA_OFFSET = np.array([-0.02, 0.02, 0.08])
_SPATULA_QUAT = Quaternion(axis=[0, 0, 1], degrees=90)
_BOARD_POS = np.array([0.7, -0.6, 0.88])
_BOARD_ROT_BOUNDS = np.deg2rad([0, 0, 5])
_TOLERANCE = np.deg2rad(10)
_TOASTED = False
_ROUNDED = False
_SANDWICH_OFFSET = np.array([0, 0, 0.05])
_SANDWICH_POS_BOUNDS = np.array([0.05, 0.05, 0])
_SANDWICH_ROT_BOUNDS = np.deg2rad([0, 0, 180])
@property
def _sandwich_anchor(self) -> Prop:
return self.board
def _initialize_env(self):
self.cabinet_base = self._preset.get_props(BaseCabinet)[0]
self.pan = Pan(self._mojo)
self.spatula = Spatula(self._mojo)
self.board = ChoppingBoard(self._mojo)
self.sandwich = Sandwich(
self._mojo, toasted=self._TOASTED, rounded_collider=self._ROUNDED
)
def _on_reset(self):
site = self.cabinet_base.sites[0]
self.pan.set_pose(
site.get_position(),
self._PAN_QUAT.elements,
self._PAN_POS_BOUNDS,
self._PAN_ROT_BOUNDS,
)
self.spatula.set_pose(
self.pan.body.get_position() + self._SPATULA_OFFSET,
self._SPATULA_QUAT.elements,
)
self.board.set_pose(self._BOARD_POS, rotation_bounds=self._BOARD_ROT_BOUNDS)
self.sandwich.set_pose(
self._sandwich_anchor.body.get_position() + self._SANDWICH_OFFSET,
position_bounds=self._SANDWICH_POS_BOUNDS,
rotation_bounds=self._SANDWICH_ROT_BOUNDS,
)
def _success(self) -> bool:
up = np.array([0, 0, 1])
sandwich_up = Quaternion(self.sandwich.body.get_quaternion()).rotate(up)
angle_to_up = np.arccos(np.clip(np.dot(sandwich_up, up), -1.0, 1.0))
angle_to_down = np.arccos(np.clip(np.dot(sandwich_up, -up), -1.0, 1.0))
if not (angle_to_up <= self._TOLERANCE or angle_to_down <= self._TOLERANCE):
return False
if not self.pan.is_colliding(self.cabinet_base.hob):
return False
if not self.sandwich.is_colliding(self.pan):
return False
return True
def _fail(self) -> bool:
if super()._fail():
return True
for side in self.robot.grippers:
if self.robot.is_gripper_holding_object(self.sandwich, side):
return True
return False
class FlipSandwich(ToastSandwich):
"""Flip sandwich using spatula."""
_SANDWICH_OFFSET = np.array([0, 0, 0.04])
_SANDWICH_POS_BOUNDS = np.array([0.01, 0.01, 0])
_SANDWICH_ROT_BOUNDS = np.deg2rad([0, 0, 180])
_ROUNDED = True
@property
def _sandwich_anchor(self) -> Prop:
return self.pan
def _success(self) -> bool:
up = np.array([0, 0, 1])
sandwich_up = Quaternion(self.sandwich.body.get_quaternion()).rotate(up)
angle_to_down = np.arccos(np.clip(np.dot(sandwich_up, -up), -1.0, 1.0))
if angle_to_down > self._TOLERANCE:
return False
if not self.pan.is_colliding(self.cabinet_base.hob):
return False
if not self.sandwich.is_colliding(self.pan):
return False
return True
class RemoveSandwich(FlipSandwich):
"""Remove sandwich from the frying pan."""
_TOASTED = True
def _success(self) -> bool:
up = np.array([0, 0, 1])
sandwich_up = Quaternion(self.sandwich.body.get_quaternion()).rotate(up)
angle_to_up = np.arccos(np.clip(np.dot(sandwich_up, up), -1.0, 1.0))
angle_to_down = np.arccos(np.clip(np.dot(sandwich_up, -up), -1.0, 1.0))
if not (angle_to_up <= self._TOLERANCE or angle_to_down <= self._TOLERANCE):
return False
if not self.sandwich.is_colliding(self.board):
return False
return True
================================================
FILE: bigym/envs/presets/cabinet.yaml
================================================
# Static cabinet
props:
- type: BaseCabinet
position: [1.2, 0, 0]
euler: [0, 0, -90]
panel_enable: true
================================================
FILE: bigym/envs/presets/cabinet_door.yaml
================================================
# Base cabinets with door
props:
- type: BaseCabinet
position: [1.2, 0, 0]
euler: [0, 0, -90]
door_left_enable: true
shelf_enable: true
================================================
FILE: bigym/envs/presets/cabinet_hob.yaml
================================================
# Base cabinet with hob
props:
- type: BaseCabinet
position: [1.2, 0, 0]
euler: [0, 0, -90]
door_left_enable: true
hob_enable: true
shelf_enable: true
================================================
FILE: bigym/envs/presets/counter_base_2.yaml
================================================
# 2 base cabinets
props:
- type: BaseCabinet
position: [1.1, 0, 0]
euler: [0, 0, -90]
shelf_enable: true
door_right_enable: true
- type: BaseCabinet
position: [1.1, -0.6, 0]
euler: [0, 0, -90]
shelf_enable: false
door_left_enable: true
================================================
FILE: bigym/envs/presets/counter_base_2_hob.yaml
================================================
# 2 base cabinets with hob
props:
- type: BaseCabinet
position: [1.1, 0, 0]
euler: [0, 0, -90]
shelf_enable: true
door_right_enable: true
hob_enable: true
- type: BaseCabinet
position: [1.1, -0.6, 0]
euler: [0, 0, -90]
shelf_enable: false
door_left_enable: true
================================================
FILE: bigym/envs/presets/counter_base_wall_1x1.yaml
================================================
# 1 base and 1 wall cabinet
props:
- type: BaseCabinet
position: [1.2, 0, 0]
euler: [0, 0, -90]
door_left_enable: true
shelf_enable: true
- type: WallCabinet
position: [ 1.2, 0, 0 ]
euler: [ 0, 0, -90 ]
glass_doors_enable: true
================================================
FILE: bigym/envs/presets/counter_base_wall_2x2.yaml
================================================
# 2 base and 2 wall cabinets
include:
- counter_base_2.yaml
props:
- type: WallCabinet
position: [1.1, 0, 0]
euler: [0, 0, -90]
glass_doors_enable: true
- type: OpenShelf
position: [1.1, -0.6, 0]
euler: [0, 0, -90]
================================================
FILE: bigym/envs/presets/counter_base_wall_3x1.yaml
================================================
# 3 base and 1 wall cabinets
props:
- type: BaseCabinet
position: [1.2, 0, 0]
euler: [ 0, 0, -90 ]
big_drawers_enable: [true, false]
small_drawers_enable: [false, false, true, true]
hob_enable: true
- type: BaseCabinet
position: [ 1.2, -0.6, 0 ]
euler: [ 0, 0, -90 ]
door_left_enable: true
shelf_enable: true
- type: BaseCabinet
position: [ 1.2, 0.6, 0 ]
euler: [ 0, 0, -90 ]
door_right_enable: true
shelf_enable: true
- type: WallCabinet
position: [ 1.2, 0, 0 ]
euler: [ 0, 0, -90 ]
doors_enable: true
vent_enable: true
================================================
FILE: bigym/envs/presets/counter_dishwasher.yaml
================================================
# Dishwasher with kitchen counter
props:
- type: Dishwasher
position: [1, 0, 0]
euler: [0, 0, -90]
- type: BaseCabinet
position: [1, 0, 0]
euler: [0, 0, -90]
walls_enable: false
- type: BaseCabinet
position: [1, -0.6, 0]
euler: [0, 0, -90]
panel_enable: true
================================================
FILE: bigym/envs/presets/counter_dishwasher_cutlery_cabinet.yaml
================================================
# Dishwasher with kitchen counter and cabinet with cutlery tray
include:
- counter_dishwasher.yaml
props:
- type: BaseCabinet
position: [1, -1.2, 0]
euler: [0, 0, -90]
small_drawers_enable: [true, true, true, true]
children:
- type: CutleryTray
parent_site: "drawer_small_4"
================================================
FILE: bigym/envs/presets/counter_dishwasher_wall_cabinet.yaml
================================================
# Dishwasher with kitchen counter and wall cabinet
include:
- counter_dishwasher.yaml
props:
- type: WallCabinet
position: [1, -0.6, 0]
euler: [0, 0, -90]
glass_doors_enable: true
================================================
FILE: bigym/envs/presets/dishwasher.yaml
================================================
# Dishwasher
props:
- type: Dishwasher
position: [1.2, 0, 0]
euler: [0, 0, -90]
================================================
FILE: bigym/envs/presets/move_plates.yaml
================================================
# Table for the "move plates" task
props:
- type: Table
position: [0.7, 0, 0]
euler: [0, 0, -90]
- type: DishDrainer
position: [0.7, 0.3, 0.95]
- type: DishDrainer
position: [0.7, -0.3, 0.95 ]
================================================
FILE: bigym/envs/presets/stack_blocks.yaml
================================================
# Two tables for the "stack blocks" task
props:
- type: Table
position: [0.7, 0, 0]
euler: [0, 0, -90]
- type: Table
position: [1.4, 0, 0]
euler: [0, 0, 90]
================================================
FILE: bigym/envs/props/__init__.py
================================================
"""Init."""
================================================
FILE: bigym/envs/props/cabintets.py
================================================
"""Modular cabinets."""
from abc import ABC
from pathlib import Path
from typing import Any
import numpy as np
from dm_control import mjcf
from mojo.elements import Body, MujocoElement
from bigym.const import ASSETS_PATH
from bigym.envs.props.prop import CollidableProp
from bigym.utils.physics_utils import set_joint_position, get_joint_position
class ModularCabinet(CollidableProp, ABC):
"""Base modular prop."""
def _post_init(self):
self._joints = self.body.joints
def set_state(self, state: np.ndarray):
"""Set normalized state of joints."""
for value, joint in zip(state, self._joints):
set_joint_position(joint, value, True)
def get_state(self) -> np.ndarray[float]:
"""Get normalized state of joints."""
return np.array([get_joint_position(joint, True) for joint in self._joints])
@staticmethod
def _toggle_body(model: mjcf.RootElement, name: str, enable: bool):
if not enable:
model.find("body", name).remove()
class BaseCabinet(ModularCabinet):
"""Modular base cabinet."""
_BIG_DRAWERS = ["drawer_big_1", "drawer_big_2"]
_SMALL_DRAWERS = [
"drawer_small_1",
"drawer_small_2",
"drawer_small_3",
"drawer_small_4",
]
_DOOR_LEFT = "door_left"
_DOOR_RIGHT = "door_right"
_PANEL = "panel"
_SHELF = "shelf"
_SHELF_BOTTOM = "shelf_bottom"
_HOB = "hob"
_WALLS = "walls"
_COUNTER = "counter"
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/kitchen/base_cabinet_600.xml"
def _parse_kwargs(self, kwargs: dict[str, Any]):
self._walls_enable = kwargs.get("walls_enable", True)
self._big_drawers_enable = kwargs.get("big_drawers_enable", None)
self._small_drawers_enable = kwargs.get("small_drawers_enable", None)
self._hob_enable = kwargs.get("hob_enable", False)
self._panel_enable = kwargs.get("panel_enable", False)
self._door_left_enable = kwargs.get("door_left_enable", False)
self._door_right_enable = kwargs.get("door_right_enable", False)
self._shelf_enable = kwargs.get("shelf_enable", False)
if self._big_drawers_enable is None:
self._big_drawers_enable = [False] * len(self._BIG_DRAWERS)
if self._small_drawers_enable is None:
self._small_drawers_enable = [False] * len(self._SMALL_DRAWERS)
assert len(self._big_drawers_enable) == len(self._BIG_DRAWERS)
assert len(self._small_drawers_enable) == len(self._SMALL_DRAWERS)
self._CACHE_SITES = (
self._hob_enable
or any(self._big_drawers_enable)
or any(self._small_drawers_enable)
)
def _on_loaded(self, model: mjcf.RootElement):
cabinet = MujocoElement(self._mojo, model)
self.shelf = Body.get(self._mojo, self._SHELF, cabinet).geoms[-1]
self.shelf_bottom = Body.get(self._mojo, self._SHELF_BOTTOM, cabinet).geoms[-1]
self.counter = Body.get(self._mojo, self._COUNTER, cabinet).geoms[-1]
self.hob = Body.get(self._mojo, self._HOB, cabinet).geoms[-1]
for name, enable in zip(self._BIG_DRAWERS, self._big_drawers_enable):
self._toggle_body(model, name, enable)
for name, enable in zip(self._SMALL_DRAWERS, self._small_drawers_enable):
self._toggle_body(model, name, enable)
self._toggle_body(model, self._WALLS, self._walls_enable)
self._toggle_body(model, self._HOB, self._hob_enable)
self._toggle_body(model, self._PANEL, self._panel_enable)
self._toggle_body(model, self._DOOR_LEFT, self._door_left_enable)
self._toggle_body(model, self._DOOR_RIGHT, self._door_right_enable)
self._toggle_body(model, self._SHELF, self._shelf_enable)
class WallCabinet(ModularCabinet):
"""Modular wall cabinet."""
_DOORS = ["door_right", "door_left"]
_GLASS_DOORS = ["door_right_glass", "door_left_glass"]
_VENT = "vent"
_SHELF = "shelf"
_SHELF_BOTTOM = "shelf_bottom"
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/kitchen/wall_cabinet_600.xml"
def _parse_kwargs(self, kwargs: dict[str, Any]):
self._doors_enable = kwargs.get("doors_enable", False)
self._glass_doors_enable = kwargs.get("glass_doors_enable", False)
self._vent_enable = kwargs.get("vent_enable", False)
def _on_loaded(self, model: mjcf.RootElement):
cabinet = MujocoElement(self._mojo, model)
self.shelf = Body.get(self._mojo, self._SHELF, cabinet).geoms[-1]
self.shelf_bottom = Body.get(self._mojo, self._SHELF_BOTTOM, cabinet).geoms[-1]
for door_name in self._DOORS:
self._toggle_body(model, door_name, self._doors_enable)
for door_name in self._GLASS_DOORS:
self._toggle_body(model, door_name, self._glass_doors_enable)
self._toggle_body(model, self._VENT, self._vent_enable)
class OpenShelf(ModularCabinet):
"""Modular open shelf."""
_SHELF = "shelf"
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/kitchen/open_shelf_600.xml"
def _on_loaded(self, model: mjcf.RootElement):
shelf = MujocoElement(self._mojo, model)
self.shelf = Body.get(self._mojo, self._SHELF, shelf).geoms[-1]
================================================
FILE: bigym/envs/props/cutlery.py
================================================
"""Cutlery props."""
from pathlib import Path
from bigym.const import ASSETS_PATH
from bigym.envs.props.prop import KinematicProp
class Fork(KinematicProp):
"""Fork."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/cutlery/fork/fork.xml"
class Knife(KinematicProp):
"""Knife."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/cutlery/knife/knife.xml"
class Spoon(KinematicProp):
"""Spoon."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/cutlery/spoon/spoon.xml"
class Spatula(KinematicProp):
"""Spatula."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/spatula/spatula.xml"
================================================
FILE: bigym/envs/props/dishwasher.py
================================================
"""Dishwasher."""
from pathlib import Path
from typing import Optional
import numpy as np
from mojo import Mojo
from mojo.elements import Joint, Site, Body, Geom
from bigym.const import ASSETS_PATH
from bigym.envs.props.prop import Prop
from bigym.utils.physics_utils import get_joint_position, set_joint_position
class DishwasherPart:
"""Part of the dishwasher."""
def __init__(
self,
mojo: Mojo,
dishwasher_body: Body,
body_name: Optional[str] = None,
joint_name: Optional[str] = None,
site_sets: Optional[list[tuple[str, int]]] = None,
):
"""Init."""
self._mojo = mojo
self.body: Optional[Body] = (
Body.get(self._mojo, body_name, dishwasher_body) if body_name else None
)
self.joint: Optional[Joint] = (
Joint.get(self._mojo, joint_name, dishwasher_body) if joint_name else None
)
self.site_sets: list[list[Site]] = []
if site_sets:
for sites_name, sites_count in site_sets:
sites_set: list[Site] = []
for i in range(sites_count):
site = Site.get(
self._mojo, f"{sites_name}_{i + 1}", dishwasher_body
)
sites_set.append(site)
self.site_sets.append(sites_set)
self.colliders: list[Geom] = Prop.get_body_colliders(self.body)
class Dishwasher(Prop):
"""Dishwasher."""
DOOR_BODY = "dishwasher/door"
DOOR_JOINT = "dishwasher/door_hinge"
TRAY_BOTTOM_BODY = "dishwasher/tray_bottom"
TRAY_BOTTOM_JOINT = "dishwasher/tray_bottom_linear"
TRAY_BOTTOM_SITES = [
("dishwasher/tray_bottom_holder_1", 11),
("dishwasher/tray_bottom_holder_2", 11),
]
TRAY_MIDDLE_BODY = "dishwasher/tray_mid"
TRAY_MIDDLE_JOINT = "dishwasher/tray_mid_linear"
TRAY_MIDDLE_SITES = [
("dishwasher/tray_mid_holder_sites_1", 11),
("dishwasher/tray_mid_holder_sites_2", 11),
]
BASKET_BODY = "dishwasher/cuttlery_basket"
BASKET_SITES = [("dishwasher/cuttlery_basket", 6)]
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/dishwasher/dishwasher.xml"
def _post_init(self):
"""Init."""
self.door = DishwasherPart(
self._mojo, self.body, self.DOOR_BODY, self.DOOR_JOINT
)
self.tray_bottom = DishwasherPart(
self._mojo,
self.body,
self.TRAY_BOTTOM_BODY,
self.TRAY_BOTTOM_JOINT,
self.TRAY_BOTTOM_SITES,
)
self.tray_middle = DishwasherPart(
self._mojo,
self.body,
self.TRAY_MIDDLE_BODY,
self.TRAY_MIDDLE_JOINT,
self.TRAY_MIDDLE_SITES,
)
self.basket = DishwasherPart(
self._mojo, self.body, self.BASKET_BODY, site_sets=self.BASKET_SITES
)
def set_state(self, door: float, bottom_tray: float, middle_tray: float):
"""Set state of dishwasher joints."""
set_joint_position(self.door.joint, door, True)
set_joint_position(self.tray_bottom.joint, bottom_tray, True)
set_joint_position(self.tray_middle.joint, middle_tray, True)
def get_state(self) -> np.ndarray:
"""Get state of dishwasher joints."""
return np.array(
[
get_joint_position(self.door.joint, True),
get_joint_position(self.tray_bottom.joint, True),
get_joint_position(self.tray_middle.joint, True),
]
)
================================================
FILE: bigym/envs/props/holders.py
================================================
"""Utensil holder."""
from abc import ABC
from pathlib import Path
from mojo.elements import Geom
from bigym.const import ASSETS_PATH
from bigym.envs.props.prop import Prop
class _Holder(Prop, ABC):
"""Base Holder Prop."""
_CACHE_COLLIDERS = True
_CACHE_SITES = True
class CutleryTray(_Holder):
"""Cutlery tray."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/cutlery_tray/cutlery_tray.xml"
class DishDrainer(_Holder):
"""Dish Drainer."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/dish_drainer/dish_drainer.xml"
def _post_init(self):
self.holders_left: list[Geom] = self.colliders[0:7]
self.holders_right: list[Geom] = self.colliders[7:14]
================================================
FILE: bigym/envs/props/items.py
================================================
"""Different pickable items."""
from pathlib import Path
from typing import Any
from dm_control import mjcf
from mujoco_utils import mjcf_utils
from bigym.const import ASSETS_PATH
from bigym.envs.props.prop import KinematicProp
class Box(KinematicProp):
"""Box."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/box/box.xml"
class Cube(KinematicProp):
"""Cube."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/cube/cube.xml"
class Sandwich(KinematicProp):
"""Sandwich."""
_COLLIDER = "collider"
_COLLIDER_ROUNDED = "collider_rounded"
_NORMAL_MODEL = "sandwich.xml"
_TOASTED_MODEL = "sandwich_toasted.xml"
@property
def _model_path(self) -> Path:
model = self._TOASTED_MODEL if self.toasted else self._NORMAL_MODEL
return ASSETS_PATH / "props/sandwich" / model
def _parse_kwargs(self, kwargs: dict[str, Any]):
self.toasted = kwargs.get("toasted", False)
self.rounded_collider = kwargs.get("rounded_collider", False)
def _on_loaded(self, model: mjcf.RootElement):
collider_to_remove = (
self._COLLIDER if self.rounded_collider else self._COLLIDER_ROUNDED
)
mjcf_utils.safe_find(model, "geom", collider_to_remove).remove()
class Wine(KinematicProp):
"""Wine."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/groceries/wine/wine.xml"
class Detergent(KinematicProp):
"""Detergent."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/groceries/detergent/detergent.xml"
class Soap(KinematicProp):
"""Soap."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/groceries/soap/soap.xml"
class Beer(KinematicProp):
"""Beer."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/groceries/beer.xml"
class Cereals(KinematicProp):
"""Cereals."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/groceries/cereal.xml"
class Crisps(KinematicProp):
"""Crisps."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/groceries/crisps.xml"
class Ketchup(KinematicProp):
"""Ketchup."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/groceries/ketchup.xml"
class Mustard(KinematicProp):
"""Mustard."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/groceries/mustard.xml"
class Soda(KinematicProp):
"""Soda."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/groceries/soda.xml"
================================================
FILE: bigym/envs/props/kitchenware.py
================================================
"""Kitchenware."""
from pathlib import Path
from bigym.const import ASSETS_PATH
from bigym.envs.props.prop import KinematicProp
class Plate(KinematicProp):
"""Plate."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/plate/plate.xml"
class Mug(KinematicProp):
"""Mug."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/mug/mug.xml"
class Pan(KinematicProp):
"""Pan."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/pan/pan.xml"
class Saucepan(KinematicProp):
"""Saucepan."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/saucepan/saucepan.xml"
class ChoppingBoard(KinematicProp):
"""Chopping Board."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/board/board.xml"
================================================
FILE: bigym/envs/props/preset.py
================================================
"""Props Preset."""
from collections import defaultdict
from pathlib import Path
from typing import Optional, Callable, TypeVar, Type
import numpy as np
from mojo import Mojo
from yaml import safe_load
import bigym.envs.props as props_module
from bigym.envs.props.prop import Prop
from bigym.utils.shared import find_class_in_module
PT = TypeVar("PT", bound=Prop)
class Preset:
"""Props Preset."""
def __init__(self, mojo: Mojo, path: Optional[Path]):
"""Init."""
self._props: list[Prop] = []
self._props_lookup: dict[type[Prop], list[Prop]] = defaultdict(list)
if path is None:
return
with open(path) as f:
config = safe_load(f)
for include in config.get("include", []):
sub_layout = Preset(mojo, path.parent / include)
self._props.extend(sub_layout._props)
for prop_config in config.get("props", []):
prop_and_children = self._load_prop(prop_config, mojo)
self._props.extend(prop_and_children)
# Build props lookup table by prop type
for prop in self._props:
self._props_lookup[type(prop)].append(prop)
def get_props(self, prop_type: Optional[Type[PT]] = None) -> list[PT]:
"""Get preset props."""
if prop_type is None:
return self._props
else:
return self._props_lookup.get(prop_type, [])
def _load_prop(
self, config, mojo: Mojo, parent: Optional[Prop] = None
) -> list[Prop]:
loaded_props = []
# Parse config
prop_type = config.pop("type")
prop_cls: Optional[type[Prop]] = find_class_in_module(props_module, prop_type)
if not prop_cls:
return loaded_props
position = self._get_float_array(config.pop("position", None), 3)
euler = self._get_float_array(config.pop("euler", None), 3, np.deg2rad)
children = config.pop("children", [])
# Load prop
if parent is None:
prop = prop_cls(mojo, **config)
else:
parent_site_name = config.pop("parent_site")
parent_site = next(
(site for site in parent.sites if site.mjcf.name == parent_site_name),
None,
)
if parent_site is None:
raise ValueError(
f"Site with name '{parent_site_name}' not found in {parent}"
)
prop = prop_cls(mojo, parent=parent_site, **config)
loaded_props.append(prop)
# Set pose
if position is not None:
prop.body.set_position(position)
if euler is not None:
prop.body.set_euler(euler)
# Load children
for child_config in children:
loaded_props.extend(self._load_prop(child_config, mojo, prop))
return loaded_props
@staticmethod
def _get_float_array(
value: Optional[list],
target_length: int,
post_process: Optional[Callable[[np.ndarray], np.ndarray]] = None,
) -> Optional[np.ndarray]:
if value is None:
return None
if len(value) != target_length:
raise ValueError(
f"Incorrect array length: {value}, expected length: {target_length}"
)
result = np.array([float(item) for item in value])
if post_process:
result = post_process(result)
return result
================================================
FILE: bigym/envs/props/prop.py
================================================
"""Abstract prop."""
from abc import abstractmethod, ABC
from pathlib import Path
from typing import Union, Iterable, Optional, Any
import numpy as np
from dm_control import mjcf
from mojo import Mojo
from mojo.elements import Body, Geom, Site, MujocoElement
from pyquaternion import Quaternion
from bigym.utils.physics_utils import has_collided_collections, get_colliders
class Prop(ABC):
"""Base prop."""
_KINEMATIC = False
_CACHE_COLLIDERS = False
_CACHE_SITES = False
__HIDDEN_POSITION = np.array([0, 0, -100])
def __init__(
self,
mojo: Mojo,
kinematic: Optional[bool] = None,
cache_colliders: Optional[bool] = None,
cache_sites: Optional[bool] = None,
parent: Optional[MujocoElement] = None,
**kwargs,
):
"""Init."""
self._parse_kwargs(kwargs or {})
kinematic = kinematic or self._KINEMATIC
cache_colliders = cache_colliders or self._CACHE_COLLIDERS
cache_sites = cache_sites or self._CACHE_SITES
self._mojo = mojo
self.body: Body = self._mojo.load_model(
str(self._model_path),
on_loaded=self._on_loaded,
parent=parent,
)
# Cache colliders
self.colliders: list[Geom] = []
if cache_colliders:
self.colliders = self.get_body_colliders(self.body)
# Cache sites
self.sites: list[Site] = []
if cache_sites:
self.sites = self.get_body_sites(self.body, self._mojo)
# Set kinematic state
self.kinematic = kinematic
if self.kinematic:
self.body.set_kinematic(True)
# Cache original geom settings
self._geoms = self.body.geoms
self._geoms_settings_cache: dict[mjcf.Element, (int, int)] = {}
for geom in self._geoms:
self._geoms_settings_cache[geom.mjcf] = (
self._mojo.physics.bind(geom.mjcf).contype,
self._mojo.physics.bind(geom.mjcf).conaffinity,
)
self._post_init()
@property
@abstractmethod
def _model_path(self) -> Path:
raise NotImplementedError
def _parse_kwargs(self, kwargs: dict[str, Any]):
"""Process initialization kwargs."""
pass
def _on_loaded(self, model: mjcf.RootElement):
"""Callback to customize prop model."""
pass
def _post_init(self):
"""Customize prop initialization."""
pass
def get_pose(self) -> np.ndarray:
"""Get pose in the world space."""
return np.concatenate(
(self.body.get_position(), self.body.get_quaternion()),
axis=-1,
)
def set_pose(
self,
position: np.ndarray = np.zeros(3),
quat: np.ndarray = Quaternion().elements,
position_bounds: np.ndarray = np.zeros(3),
rotation_bounds: np.ndarray = np.zeros(3),
):
"""Set pose in the world space."""
offset_pos = np.random.uniform(-position_bounds, position_bounds)
pos = position + offset_pos
offset_rot = np.random.uniform(-rotation_bounds, rotation_bounds)
quat = (
Quaternion(quat)
* Quaternion(axis=[1, 0, 0], angle=offset_rot[0])
* Quaternion(axis=[0, 1, 0], angle=offset_rot[1])
* Quaternion(axis=[0, 0, 1], angle=offset_rot[2])
)
self.body.set_position(pos, True)
self.body.set_quaternion(quat.elements, True)
def disable(self):
"""Disable prop."""
for geom in self._geoms:
geom = self._mojo.physics.bind(geom.mjcf)
geom.contype = 0
geom.conaffinity = 0
if self.body.is_kinematic():
freejoint = self._mojo.physics.bind(self.body.mjcf.freejoint)
freejoint.damping = 10e6
self.body.set_position(self.__HIDDEN_POSITION, True)
def enable(self):
"""Enable prop."""
for geom in self._geoms:
contype, conaffinity = self._geoms_settings_cache[geom.mjcf]
geom = self._mojo.physics.bind(geom.mjcf)
geom.contype = contype
geom.conaffinity = conaffinity
if self.body.is_kinematic():
freejoint = self._mojo.physics.bind(self.body.mjcf.freejoint)
freejoint.damping = 0
def get_velocities(self) -> np.ndarray:
"""Get velocities of the free body."""
if self.kinematic:
return np.array(self._mojo.physics.bind(self.body.mjcf.freejoint).qvel)
else:
return np.zeros(0)
def is_static(self, atol_pos: float = 1.0e-3):
"""Check if object's position is static."""
velocities = self.get_velocities()
return np.allclose(velocities[:3], 0, atol=atol_pos)
def is_colliding(self, other: Union[Geom, Iterable[Geom], "Prop"]) -> bool:
"""Check collision between two props."""
other_colliders = get_colliders(other)
return has_collided_collections(
self._mojo.physics, self.colliders, other_colliders
)
@staticmethod
def get_body_colliders(body: Body) -> list[Geom]:
"""Get all colliders of the body."""
return [g for g in body.geoms if g.is_collidable()]
@staticmethod
def get_body_sites(body: Body, mojo: Mojo) -> list[Site]:
"""Get all sites of the body."""
sites = body.mjcf.find_all("site")
return [Site(mojo, site_mjcf) for site_mjcf in sites]
class CollidableProp(Prop, ABC):
"""Collidable prop."""
_CACHE_COLLIDERS = True
class KinematicProp(Prop, ABC):
"""Kinematic collidable prop."""
_KINEMATIC = True
_CACHE_COLLIDERS = True
================================================
FILE: bigym/envs/props/tables.py
================================================
"""Tables."""
from pathlib import Path
from bigym.const import ASSETS_PATH
from bigym.envs.props.prop import CollidableProp
class Table(CollidableProp):
"""Default Table."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/table/table.xml"
class SmallTable(CollidableProp):
"""Shorter version of the default table."""
@property
def _model_path(self) -> Path:
return ASSETS_PATH / "props/table_dishwasher/table_dishwasher.xml"
================================================
FILE: bigym/envs/reach_target.py
================================================
"""Set of reach target tasks."""
from abc import ABC
from dataclasses import dataclass, field
import numpy as np
from gymnasium import spaces
from mojo import Mojo
from mojo.elements import Body, Geom
from mojo.elements.consts import GeomType
from bigym.bigym_env import BiGymEnv
from bigym.const import HandSide
from bigym.robots.robot import Robot
@dataclass
class TargetConfig:
"""Target Config."""
target_hands: list[HandSide]
reset_position: np.ndarray = field(default_factory=lambda: np.zeros(3))
size: np.ndarray = field(default_factory=lambda: np.array([0.05, 0.05, 0.05]))
color_default: np.ndarray = field(default_factory=lambda: np.array([1, 0, 0, 1]))
color_highlight: np.ndarray = field(default_factory=lambda: np.array([1, 0, 0, 1]))
class Target:
"""Target sphere."""
def __init__(self, mojo: Mojo, robot: Robot, config: TargetConfig):
"""Init."""
self._robot = robot
self._config = config
self.body = Body.create(mojo)
self.geom: Geom = Geom.create(
mojo,
parent=self.body,
geom_type=GeomType.SPHERE,
size=config.size,
color=config.color_default,
mass=0,
)
self.geom.set_collidable(False)
def reset_position(self, offset: np.ndarray = np.zeros(3)):
"""Reset position of the target."""
self.body.set_position(self._config.reset_position + offset)
def distance(self, pos: np.ndarray) -> float:
"""Get distance to target."""
return float(np.linalg.norm(self.body.get_position() - pos))
def is_reached(self, tolerance: float) -> bool:
"""Check if target is reached."""
for side in self._config.target_hands:
if side not in self._robot.grippers:
continue
hand_pos = self._robot.get_hand_pos(side)
is_reached = self.distance(hand_pos) <= tolerance
self.set_highlight(is_reached)
if is_reached:
return True
return False
def set_highlight(self, highlight: bool):
"""Toggle target highlight."""
self.geom.set_color(
self._config.color_highlight if highlight else self._config.color_default
)
class _ReachTargetEnv(BiGymEnv, ABC):
"""Base reach target environment."""
TARGET_CONFIGS = [
TargetConfig(
target_hands=[HandSide.LEFT, HandSide.RIGHT],
reset_position=np.array([0.5, 0, 1]),
color_default=np.array([0.3, 0, 0, 1]),
color_highlight=np.array([1, 0, 0, 1]),
)
]
POSITION_BOUNDS = np.array([0.1, 0.1, 0.1])
TOLERANCE = 0.1
def _initialize_env(self):
self.targets: list[Target] = []
for config in self.TARGET_CONFIGS:
self.targets.append(Target(self._mojo, self.robot, config))
def _on_reset(self):
for target in self.targets:
offset = np.random.uniform(-self.POSITION_BOUNDS, self.POSITION_BOUNDS)
target.reset_position(offset)
target.set_highlight(False)
def _success(self) -> bool:
for target in self.targets:
if not target.is_reached(self.TOLERANCE):
return False
return True
def _on_step(self):
"""Highlight spheres even in fast mode."""
self._success()
class ReachTarget(_ReachTargetEnv):
"""Reach the target with either left or right wrist."""
def _get_task_privileged_obs_space(self):
return {
"target_position": spaces.Box(
low=-np.inf, high=np.inf, shape=(3,), dtype=np.float32
)
}
def _get_task_privileged_obs(self):
return {
"target_position": np.array(
self.targets[0].body.get_position(), np.float32
).copy()
}
class ReachTargetSingle(ReachTarget):
"""Reach the target with specific wrist."""
TARGET_CONFIGS = [
TargetConfig(
target_hands=[HandSide.LEFT],
reset_position=np.array([0.5, 0, 1]),
color_default=np.array([0.3, 0, 0, 1]),
color_highlight=np.array([1, 0, 0, 1]),
)
]
class ReachTargetDual(_ReachTargetEnv):
"""Reach 2 targets, one with each arm."""
TARGET_CONFIGS = [
TargetConfig(
target_hands=[HandSide.LEFT],
reset_position=np.array([0.5, 0.2, 1]),
color_default=np.array([0.3, 0, 0, 1]),
color_highlight=np.array([1, 0, 0, 1]),
),
TargetConfig(
target_hands=[HandSide.RIGHT],
reset_position=np.array([0.5, -0.2, 1]),
color_default=np.array([0, 0.3, 0, 1]),
color_highlight=np.array([0, 1, 0, 1]),
),
]
def _get_task_privileged_obs_space(self):
return {
"target_position_left": spaces.Box(
low=-np.inf, high=np.inf, shape=(3,), dtype=np.float32
),
"target_position_right": spaces.Box(
low=-np.inf, high=np.inf, shape=(3,), dtype=np.float32
),
}
def _get_task_privileged_obs(self):
return {
"target_position_left": np.array(
self.targets[0].body.get_position(), np.float32
).copy(),
"target_position_right": np.array(
self.targets[1].body.get_position(), np.float32
).copy(),
}
================================================
FILE: bigym/envs/xmls/3D_MODELS_ATTRIBUTION.md
================================================
# 3D Models Attribution
This document provides the attribution details for the 3D models included in this repository. The models are used under various Creative Commons licenses and have been modified in some cases. Below are the details for each model:
## Table of Contents
- [Groceries](#groceries)
- [Kitchen Set](#kitchen-set)
- [Kitchen Utensils](#kitchen-utensils)
- [Cutlery](#cutlery)
- [Tables](#tables)
- [Plate](#plate)
- [Mug](#mug)
- [Cutlery Tray](#cutlery-tray)
---
## Groceries
- **Asset(s)**: [`bigym/envs/xmls/props/groceries/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/groceries/assets)
- **Author**: [tulex_art](https://sketchfab.com/CassioFernandes)
- **Source**: [Sketchfab](https://skfb.ly/6RCNy)
- **License**: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)
---
## Kitchen Set
- **Asset(s)**: [`bigym/envs/xmls/props/kitchen/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/kitchen/assets)
- **Author**: [RedKit](https://sketchfab.com/redkitpro)
- **Source**: [Sketchfab](https://skfb.ly/6SXBW)
- **License**: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)
---
## Kitchen Utensils
- **Asset(s)**:
- [`bigym/envs/xmls/props/board/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/board/assets)
- [`bigym/envs/xmls/props/pan/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/pan/assets)
- [`bigym/envs/xmls/props/saucepan/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/saucepan/assets)
- [`bigym/envs/xmls/props/spatula/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/spatula/assets)
- [`bigym/envs/xmls/props/groceries/detergent/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/groceries/detergent/assets)
- [`bigym/envs/xmls/props/groceries/soap/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/groceries/soap/assets)
- [`bigym/envs/xmls/props/groceries/wine/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/groceries/wine/assets)
- **Author**: [Nicolai Kilstrup](https://sketchfab.com/nkilstrup)
- **Source**: [Sketchfab](https://skfb.ly/oFoUn)
- **License**: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)
---
## Box
- **Asset(s)**: [`bigym/envs/xmls/props/box/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/box/assets)
- **Author**: [Pricey1600](https://sketchfab.com/Pricey1600)
- **Source**: [Sketchfab](https://skfb.ly/6ZWFF)
- **License**: [CC BY NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)
---
## Cutlery
- **Asset(s)**:
- [`bigym/envs/xmls/props/cutlery/knife/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/cutlery/knife/assets)
- [`bigym/envs/xmls/props/cutlery/fork/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/cutlery/fork/assets)
- [`bigym/envs/xmls/props/cutlery/spoon/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/cutlery/spoon/assets)
- **Author**: [thebasemesh.com](https://thebasemesh.com)
- **Source**: [thebasemesh.com](https://thebasemesh.com)
- **License**: [CC0](https://creativecommons.org/publicdomain/zero/1.0/)
---
## Tables
- **Asset(s)**:
- [`bigym/envs/xmls/props/table/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/table/assets)
- [`bigym/envs/xmls/props/table_dishwasher/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/table_dishwasher/assets)
- **Author**: [thebasemesh.com](https://thebasemesh.com)
- **Source**: [thebasemesh.com](https://thebasemesh.com)
- **License**: [CC0](https://creativecommons.org/publicdomain/zero/1.0/)
---
## Plate
- **Asset(s)**: [`bigym/envs/xmls/props/plate/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/plate/assets)
- **Author**: [thebasemesh.com](https://thebasemesh.com)
- **Source**: [thebasemesh.com](https://thebasemesh.com)
- **License**: [CC0](https://creativecommons.org/publicdomain/zero/1.0/)
---
## Mug
- **Asset(s)**: [`bigym/envs/xmls/props/mug/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/mug/assets)
- **Author**: [thebasemesh.com](https://thebasemesh.com)
- **Source**: [thebasemesh.com](https://thebasemesh.com)
- **License**: [CC0](https://creativecommons.org/publicdomain/zero/1.0/)
---
## Cutlery Tray
- **Asset(s)**: [`bigym/envs/xmls/props/cutlery_tray/assets`](https://github.com/chernyadev/bigym/tree/master/bigym/envs/xmls/props/cutlery_tray/assets)
- **Author**: [thebasemesh.com](https://thebasemesh.com)
- **Source**: [thebasemesh.com](https://thebasemesh.com)
- **License**: [CC0](https://creativecommons.org/publicdomain/zero/1.0/)
================================================
FILE: bigym/envs/xmls/google_robot/assets/link_base_v.obj
================================================
# This file uses centimeters as units for non-parametric coordinates.
mtllib link_base.mtl
v -0.394271 -0.073010 -0.012526
v -0.398574 0.000000 0.000102
v -0.057676 -0.054915 0.589500
v -0.064463 -0.062232 0.265231
v -0.029247 -0.072323 0.589500
v 0.000000 -0.089756 0.265231
v 0.000000 -0.094455 0.241341
v -0.387599 -0.108978 0.000232
v -0.394529 -0.072428 0.000156
v -0.377556 -0.063941 0.205559
v -0.380629 -0.028275 0.205553
v -0.380599 0.000000 0.205554
v -0.034722 -0.082396 0.265231
v -0.036382 -0.085919 0.244272
v -0.065739 -0.065695 0.246076
v -0.078304 0.000000 0.589500
v -0.089606 0.000000 0.265231
v -0.083962 -0.030899 0.265231
v -0.072959 -0.028473 0.589500
v -0.371613 0.000000 -0.036951
v -0.385216 0.000000 -0.033384
v -0.377180 -0.142534 -0.012392
v -0.387366 -0.109239 -0.012477
v -0.383330 -0.108218 -0.025482
v -0.390128 -0.072411 -0.025505
v -0.381336 -0.071140 -0.033765
v -0.374724 -0.106038 -0.033757
v -0.373402 -0.140859 -0.025441
v -0.096958 0.000000 0.230117
v -0.092552 -0.032118 0.229678
v -0.105971 -0.036574 0.215731
v -0.397760 0.000000 -0.013383
v -0.393873 0.000000 -0.025392
v -0.355065 -0.131526 -0.037303
v -0.365270 -0.137252 -0.033745
v -0.355710 -0.153619 -0.033735
v -0.346818 -0.145765 -0.037303
v -0.367823 -0.069185 -0.037305
v -0.362839 -0.103169 -0.037301
v -0.362876 -0.160785 -0.025409
v -0.366184 -0.163168 -0.012327
v 0.063547 -0.063355 0.265231
v 0.054402 -0.056372 0.589500
v 0.072671 -0.029276 0.589500
v 0.078304 0.000000 0.589500
v 0.089606 0.000000 0.265231
v 0.030361 -0.071804 0.589500
v 0.034035 -0.081857 0.265231
v 0.000000 -0.078454 0.589500
v 0.037752 -0.086299 0.239647
v -0.368532 -0.100251 0.210269
v -0.371023 -0.100858 0.205577
v -0.378071 -0.028200 0.210261
v -0.378041 0.000000 0.210261
v -0.373128 0.000000 0.212386
v -0.130000 0.000000 0.212386
v -0.373161 -0.028058 0.212386
v -0.125222 -0.043262 0.212386
v -0.110655 0.000000 0.216681
v -0.039784 -0.099594 0.225621
v -0.091013 0.000000 0.246497
v -0.071183 -0.075615 0.227141
v -0.086254 -0.029369 0.247111
v 0.128879 0.000000 -0.037600
v -0.344553 -0.164741 -0.033733
v -0.329265 -0.173877 -0.033765
v -0.336424 -0.155437 -0.037303
v -0.349979 -0.173677 -0.025405
v -0.377110 -0.142913 0.000364
v -0.352480 -0.176906 -0.012317
v -0.366231 -0.163335 0.000453
v 0.082442 -0.034125 0.265231
v 0.042814 -0.103641 0.219488
v 0.000000 -0.109101 0.223195
v -0.358620 -0.129618 0.210283
v -0.360965 -0.130666 0.205613
v -0.350677 -0.148044 0.205639
v -0.352591 -0.177192 0.000481
v -0.370171 -0.063074 0.212386
v -0.354160 -0.127625 0.212386
v -0.344698 -0.143683 0.212386
v -0.330765 -0.156465 0.212386
v -0.301387 -0.165392 0.212386
v -0.081858 -0.089372 0.214905
v -0.102179 -0.098312 0.212386
v -0.316954 -0.168957 0.210259
v -0.316037 -0.164164 0.212386
v -0.333398 -0.160545 0.210291
v -0.348611 -0.146537 0.210292
v -0.363765 -0.099092 0.212386
v -0.053197 -0.145182 0.212386
v 0.117996 -0.177647 -0.029440
v 0.116503 -0.184257 -0.021369
v 0.113768 -0.178088 -0.031127
v 0.127595 -0.058862 -0.037508
v 0.127851 -0.107381 -0.035247
v 0.123493 -0.106996 -0.037397
v 0.133499 0.000000 -0.035897
v 0.136621 0.000000 -0.031406
v 0.122374 -0.167959 -0.028417
v 0.119598 -0.168726 -0.033881
v 0.122685 -0.148606 -0.035275
v 0.115322 -0.168459 -0.036125
v 0.053090 -0.161500 -0.037503
v 0.054590 -0.169203 -0.036664
v -0.326357 -0.160671 -0.037305
v -0.310366 -0.174920 -0.033520
v -0.310366 -0.161797 -0.037000
v -0.055174 -0.172688 -0.035275
v -0.058255 -0.180427 -0.030625
v -0.310366 -0.184377 -0.025456
v -0.062079 -0.161500 -0.019725
v -0.061876 -0.185891 -0.022921
v -0.065019 -0.188861 -0.011961
v 0.000000 -0.161500 -0.037503
v -0.064950 -0.161500 0.000115
v -0.058024 -0.161500 0.028182
v -0.053090 -0.161500 -0.037503
v -0.310366 -0.188187 -0.012642
v -0.331410 -0.183015 -0.025506
v -0.332416 -0.187049 -0.012527
v -0.310403 -0.188946 -0.000098
v -0.332466 -0.187149 0.000153
v 0.091338 0.000000 0.236185
v 0.085357 -0.036471 0.236007
v 0.067416 -0.067201 0.237676
v 0.074694 -0.079482 0.214584
v 0.096157 0.000000 0.209584
v 0.045226 -0.126050 0.208831
v -0.335313 -0.162370 0.205637
v -0.317451 -0.171439 0.205548
v -0.301341 -0.173428 0.205607
v -0.301387 -0.170194 0.210429
v -0.045796 -0.121340 0.214592
v 0.000000 -0.134896 0.213715
v 0.119559 -0.180191 -0.019054
v 0.120907 -0.175075 -0.025075
v 0.115434 -0.186693 -0.011455
v 0.114551 -0.186692 -0.000145
v 0.111561 -0.188248 -0.012150
v 0.112538 -0.185619 -0.022601
v 0.130632 -0.107668 -0.029695
v 0.125431 -0.149009 -0.029613
v 0.132000 -0.058707 -0.035398
v 0.134832 -0.058856 -0.029934
v -0.049680 -0.185676 0.043540
v -0.059036 -0.186799 0.028642
v -0.034349 -0.184702 0.056464
v -0.033841 -0.161500 0.055598
v -0.048867 -0.161500 0.042861
v -0.017308 -0.161500 0.062665
v 0.062079 -0.161500 -0.019725
v 0.062135 -0.186844 -0.022818
v 0.034652 -0.161500 0.055112
v 0.018519 -0.161500 0.061528
v 0.048867 -0.161500 0.042861
v 0.065015 -0.189211 -0.013378
v 0.064950 -0.161500 -0.001556
v 0.066081 -0.189093 -0.001620
v -0.017551 -0.184166 0.063590
v -0.066211 -0.188952 0.000099
v 0.083933 -0.094354 0.197542
v 0.106014 0.000000 0.186124
v 0.101601 -0.049891 0.187474
v 0.091365 -0.042372 0.209635
v 0.065619 -0.167324 0.197637
v 0.040320 -0.147108 0.208347
v 0.044533 -0.166307 0.206029
v -0.000750 -0.170239 0.209827
v -0.000708 -0.173496 0.205051
v -0.000750 -0.165455 0.211960
v 0.000000 -0.148794 0.212425
v 0.074546 -0.175351 0.180549
v 0.077341 -0.172602 0.184042
v 0.061434 -0.174471 0.192196
v 0.063709 -0.171605 0.196007
v 0.042784 -0.173926 0.199404
v 0.044062 -0.170942 0.203795
v 0.110424 -0.180305 0.080890
v 0.117774 -0.182497 -0.000295
v 0.118552 -0.182333 -0.010668
v 0.106197 -0.183050 0.078535
v 0.110745 -0.188994 -0.000256
v 0.108876 -0.179745 0.086671
v 0.092270 -0.182520 0.085536
v 0.060738 -0.186827 0.028410
v 0.049635 -0.185687 0.043506
v 0.113073 -0.176574 0.080890
v 0.121315 -0.145494 0.080890
v 0.134357 0.000000 0.088123
v 0.136739 0.000000 0.080890
v 0.133507 -0.057737 0.080890
v 0.059730 -0.161500 0.028075
v 0.035126 -0.184747 0.055956
v 0.018735 -0.184256 0.062446
v 0.094760 -0.175535 0.145839
v 0.084830 -0.176563 0.164485
v 0.087891 -0.173844 0.168229
v 0.090741 -0.170153 0.168284
v 0.079762 -0.168591 0.185110
v 0.106514 -0.174742 0.091374
v 0.091813 -0.181854 0.094370
v 0.092875 -0.179371 0.090352
v 0.128117 -0.102345 0.080890
v 0.111033 -0.175744 0.087701
v 0.127726 0.000000 0.091909
v 0.131290 -0.056847 0.088385
v 0.121370 -0.057800 0.123388
v 0.124391 0.000000 0.121914
v 0.092737 -0.179878 0.120553
v 0.090592 -0.178024 0.145133
v 0.097356 -0.171841 0.145915
v 0.097239 -0.177938 0.120611
v 0.094151 -0.174379 0.092401
v 0.100205 -0.142502 0.092372
v 0.112673 -0.143365 0.091566
v 0.114437 -0.054218 0.092370
v 0.124753 -0.055954 0.091531
v 0.117591 0.000000 0.092366
v 0.124543 -0.054841 0.094157
v 0.126867 0.000000 0.094167
v 0.099617 -0.180848 0.094108
v 0.103394 -0.176031 0.094194
v 0.100530 -0.174163 0.120499
v -0.006888 0.000000 -0.037600
v 0.107255 -0.098903 0.166425
v 0.116332 -0.099614 0.123407
v 0.118353 -0.099459 0.094172
v 0.125410 -0.101444 0.088739
v 0.119798 -0.100517 0.091560
v 0.108287 -0.098523 0.092377
v -0.371487 -0.028882 -0.037343
v -0.385122 -0.029452 -0.033611
v -0.393911 -0.029757 -0.025468
v -0.397981 -0.029900 -0.012899
v -0.398434 -0.029695 0.000107
v -0.375035 -0.063730 0.210263
v 0.118305 -0.147950 -0.037458
v 0.000028 -0.183997 0.065848
v 0.107769 -0.144208 0.121119
v 0.095875 -0.143397 0.173453
v 0.110364 -0.144605 0.094152
v 0.074335 -0.140120 0.197010
v 0.115335 -0.056981 0.160423
v 0.119673 0.000000 0.158054
v 0.083955 0.000000 0.427365
v 0.077556 -0.031700 0.427365
v 0.058974 -0.059864 0.427365
v 0.032198 -0.076831 0.427365
v 0.000000 -0.084105 0.427365
v -0.031238 -0.077359 0.427365
v -0.061070 -0.058573 0.427365
v -0.078461 -0.029686 0.427365
v -0.083955 0.000000 0.427365
v 0.136682 0.000000 -0.002193
v 0.134487 -0.058510 -0.001477
v 0.130746 -0.106336 -0.001389
v 0.125048 -0.149483 -0.001421
v 0.118205 -0.144463 0.088272
v 0.000827 -0.161500 -0.019725
v -0.310309 -0.133239 0.212386
v -0.322896 0.000000 0.212386
v -0.316893 -0.044472 0.212386
v -0.064208 -0.165392 0.212386
v -0.067281 -0.170320 0.210215
v -0.069506 -0.173455 0.205521
v -0.313049 0.000000 -0.037600
v 0.058116 -0.180051 -0.031885
v 0.104615 -0.179341 0.089605
v 0.098808 -0.182504 0.085764
v 0.103689 -0.182640 0.083960
v -0.000141 0.000000 0.589502
v 0.023080 -0.165722 0.210049
v 0.022290 -0.170467 0.207923
v 0.020826 -0.173624 0.203378
v -0.313289 -0.098196 0.212386
v 0.102771 -0.143913 0.143189
v 0.094032 -0.174210 0.093996
v 0.100544 -0.143554 0.093961
v 0.108580 -0.098992 0.093974
v 0.114750 -0.054530 0.093963
v 0.117489 0.000000 0.093966
v 0.094904 -0.181801 0.094277
v 0.065009 -0.188045 0.012270
v 0.064186 -0.161500 0.012895
v -0.063497 -0.161500 0.014640
v -0.064684 -0.187903 0.014001
v 0.000000 -0.161500 0.064916
v -0.394271 0.073010 -0.012526
v -0.057676 0.054915 0.589500
v -0.064463 0.062232 0.265231
v -0.029247 0.072323 0.589500
v 0.000000 0.089756 0.265231
v 0.000000 0.094455 0.241341
v -0.387599 0.108978 0.000232
v -0.394529 0.072428 0.000156
v -0.377556 0.063941 0.205559
v -0.380629 0.028275 0.205553
v -0.034722 0.082396 0.265231
v -0.036382 0.085919 0.244272
v -0.065739 0.065695 0.246076
v -0.083962 0.030899 0.265231
v -0.072959 0.028473 0.589500
v -0.377180 0.142534 -0.012392
v -0.387366 0.109239 -0.012477
v -0.383330 0.108218 -0.025482
v -0.390128 0.072411 -0.025505
v -0.381336 0.071140 -0.033765
v -0.374724 0.106038 -0.033757
v -0.373402 0.140859 -0.025441
v -0.092552 0.032118 0.229678
v -0.105971 0.036574 0.215731
v -0.355065 0.131526 -0.037303
v -0.365270 0.137252 -0.033745
v -0.355710 0.153619 -0.033735
v -0.346818 0.145765 -0.037303
v -0.367823 0.069185 -0.037305
v -0.362839 0.103169 -0.037301
v -0.362876 0.160785 -0.025409
v -0.366184 0.163168 -0.012327
v 0.063547 0.063355 0.265231
v 0.054402 0.056372 0.589500
v 0.072671 0.029276 0.589500
v 0.030361 0.071804 0.589500
v 0.034035 0.081857 0.265231
v 0.000000 0.078454 0.589500
v 0.037752 0.086299 0.239647
v -0.368532 0.100251 0.210269
v -0.371023 0.100858 0.205577
v -0.378071 0.028200 0.210261
v -0.373161 0.028058 0.212386
v -0.125222 0.043262 0.212386
v -0.039784 0.099594 0.225621
v -0.071183 0.075615 0.227141
v -0.086254 0.029369 0.247111
v -0.344553 0.164741 -0.033733
v -0.329265 0.173877 -0.033765
v -0.336424 0.155437 -0.037303
v -0.349979 0.173677 -0.025405
v -0.377110 0.142913 0.000364
v -0.352480 0.176906 -0.012317
v -0.366231 0.163335 0.000453
v 0.082442 0.034125 0.265231
v 0.042814 0.103641 0.219488
v 0.000000 0.109101 0.223195
v -0.358620 0.129618 0.210283
v -0.360965 0.130666 0.205613
v -0.350677 0.148044 0.205639
v -0.352591 0.177192 0.000481
v -0.370171 0.063074 0.212386
v -0.354160 0.127625 0.212386
v -0.344698 0.143683 0.212386
v -0.330765 0.156465 0.212386
v -0.301387 0.165392 0.212386
v -0.081858 0.089372 0.214905
v -0.102179 0.098312 0.212386
v -0.316954 0.168957 0.210259
v -0.316037 0.164164 0.212386
v -0.333398 0.160545 0.210291
v -0.348611 0.146537 0.210292
v -0.363765 0.099092 0.212386
v -0.053197 0.145182 0.212386
v 0.117996 0.177647 -0.029440
v 0.116503 0.184257 -0.021369
v 0.113768 0.178088 -0.031127
v 0.127595 0.058862 -0.037508
v 0.127851 0.107381 -0.035247
v 0.123493 0.106996 -0.037397
v 0.122374 0.167959 -0.028417
v 0.119598 0.168726 -0.033881
v 0.122685 0.148606 -0.035275
v 0.115322 0.168459 -0.036125
v 0.053090 0.161500 -0.037503
v 0.054590 0.169203 -0.036664
v -0.326357 0.160671 -0.037305
v -0.310366 0.174920 -0.033520
v -0.310366 0.161797 -0.037000
v -0.055174 0.172688 -0.035275
v -0.058255 0.180427 -0.030625
v -0.310366 0.184377 -0.025456
v -0.062079 0.161500 -0.019725
v -0.061876 0.185891 -0.022921
v -0.065019 0.188861 -0.011961
v 0.000000 0.161500 -0.037503
v -0.064950 0.161500 0.000115
v -0.058024 0.161500 0.028182
v -0.053090 0.161500 -0.037503
v -0.310366 0.188187 -0.012642
v -0.331410 0.183015 -0.025506
v -0.332416 0.187049 -0.012527
v -0.310403 0.188946 -0.000098
v -0.332466 0.187149 0.000153
v 0.085357 0.036471 0.236007
v 0.067416 0.067201 0.237676
v 0.074694 0.079482 0.214584
v 0.045226 0.126050 0.208831
v -0.335313 0.162370 0.205637
v -0.317451 0.171439 0.205548
v -0.301341 0.173428 0.205607
v -0.301387 0.170194 0.210429
v -0.045796 0.121340 0.214592
v 0.000000 0.134896 0.213715
v 0.119559 0.180191 -0.019054
v 0.120907 0.175075 -0.025075
v 0.115434 0.186693 -0.011455
v 0.114551 0.186692 -0.000145
v 0.111561 0.188248 -0.012150
v 0.112538 0.185619 -0.022601
v 0.130632 0.107668 -0.029695
v 0.125431 0.149009 -0.029613
v 0.132000 0.058707 -0.035398
v 0.134832 0.058856 -0.029934
v -0.049680 0.185676 0.043540
v -0.059036 0.186799 0.028642
v -0.034349 0.184702 0.056464
v -0.033841 0.161500 0.055598
v -0.048867 0.161500 0.042861
v -0.017308 0.161500 0.062665
v 0.062079 0.161500 -0.019725
v 0.062135 0.186844 -0.022818
v 0.034652 0.161500 0.055112
v 0.018519 0.161500 0.061528
v 0.048867 0.161500 0.042861
v 0.065015 0.189211 -0.013378
v 0.064950 0.161500 -0.001556
v 0.066081 0.189093 -0.001620
v -0.017551 0.184166 0.063590
v -0.066211 0.188952 0.000099
v 0.083933 0.094354 0.197542
v 0.101601 0.049891 0.187474
v 0.091365 0.042372 0.209635
v 0.065619 0.167324 0.197637
v 0.040320 0.147108 0.208347
v 0.044533 0.166307 0.206029
v -0.000750 0.170239 0.209827
v -0.000708 0.173496 0.205051
v -0.000750 0.165455 0.211960
v 0.000000 0.148794 0.212425
v 0.074546 0.175351 0.180549
v 0.077341 0.172602 0.184042
v 0.061434 0.174471 0.192196
v 0.063709 0.171605 0.196007
v 0.042784 0.173926 0.199404
v 0.044062 0.170942 0.203795
v 0.110424 0.180305 0.080890
v 0.117774 0.182497 -0.000295
v 0.118552 0.182333 -0.010668
v 0.106197 0.183050 0.078535
v 0.110745 0.188994 -0.000256
v 0.108876 0.179745 0.086671
v 0.092270 0.182520 0.085536
v 0.060738 0.186827 0.028410
v 0.049635 0.185687 0.043506
v 0.113073 0.176574 0.080890
v 0.121315 0.145494 0.080890
v 0.133507 0.057737 0.080890
v 0.059730 0.161500 0.028075
v 0.035126 0.184747 0.055956
v 0.018735 0.184256 0.062446
v 0.094760 0.175535 0.145839
v 0.084830 0.176563 0.164485
v 0.087891 0.173844 0.168229
v 0.090741 0.170153 0.168284
v 0.079762 0.168591 0.185110
v 0.106514 0.174742 0.091374
v 0.091813 0.181854 0.094370
v 0.092875 0.179371 0.090352
v 0.128117 0.102345 0.080890
v 0.111033 0.175744 0.087701
v 0.131290 0.056847 0.088385
v 0.121370 0.057800 0.123388
v 0.092737 0.179878 0.120553
v 0.090592 0.178024 0.145133
v 0.097356 0.171841 0.145915
v 0.097239 0.177938 0.120611
v 0.094151 0.174379 0.092401
v 0.100205 0.142502 0.092372
v 0.112673 0.143365 0.091566
v 0.114437 0.054218 0.092370
v 0.124753 0.055954 0.091531
v 0.124543 0.054841 0.094157
v 0.099617 0.180848 0.094108
v 0.103394 0.176031 0.094194
v 0.100530 0.174163 0.120499
v 0.107255 0.098903 0.166425
v 0.116332 0.099614 0.123407
v 0.118353 0.099459 0.094172
v 0.125410 0.101444 0.088739
v 0.119798 0.100517 0.091560
v 0.108287 0.098523 0.092377
v -0.371487 0.028882 -0.037343
v -0.385122 0.029452 -0.033611
v -0.393911 0.029757 -0.025468
v -0.397981 0.029900 -0.012899
v -0.398434 0.029695 0.000107
v -0.375035 0.063730 0.210263
v 0.118305 0.147950 -0.037458
v -0.000014 0.183997 0.065848
v 0.107769 0.144208 0.121119
v 0.095875 0.143397 0.173453
v 0.110364 0.144605 0.094152
v 0.074335 0.140120 0.197010
v 0.115335 0.056981 0.160423
v 0.077556 0.031700 0.427365
v 0.058974 0.059864 0.427365
v 0.032198 0.076831 0.427365
v 0.000000 0.084105 0.427365
v -0.031238 0.077359 0.427365
v -0.061070 0.058573 0.427365
v -0.078461 0.029686 0.427365
v 0.134487 0.058510 -0.001477
v 0.130746 0.106336 -0.001389
v 0.125048 0.149483 -0.001421
v 0.118205 0.144463 0.088272
v 0.000827 0.161500 -0.019725
v -0.310309 0.133239 0.212386
v -0.316893 0.044472 0.212386
v -0.064208 0.165392 0.212386
v -0.067281 0.170320 0.210215
v -0.069506 0.173455 0.205521
v 0.058116 0.180051 -0.031885
v 0.104615 0.179341 0.089605
v 0.098808 0.182504 0.085764
v 0.103689 0.182640 0.083960
v 0.023080 0.165722 0.210049
v 0.022290 0.170467 0.207923
v 0.020826 0.173624 0.203378
v -0.313289 0.098196 0.212386
v 0.102771 0.143913 0.143189
v 0.094032 0.174210 0.093996
v 0.100544 0.143554 0.093961
v 0.108580 0.098992 0.093974
v 0.114750 0.054530 0.093963
v 0.094904 0.181801 0.094277
v 0.065009 0.188045 0.012270
v 0.064186 0.161500 0.012895
v -0.063497 0.161500 0.014640
v -0.064684 0.187903 0.014001
v 0.000000 0.161500 0.064916
v 0.051217 0.000000 0.919939
v 0.043415 0.000000 0.924702
v 0.035887 0.000000 0.930200
v 0.028933 0.000000 0.936329
v 0.023123 0.000000 0.942930
v 0.018441 0.000000 0.949774
v 0.013176 0.000000 0.965147
v 0.014850 0.000000 0.957504
v 0.018087 0.000000 0.999815
v 0.015007 0.000000 0.986327
v 0.013218 0.000000 0.974645
v 0.025436 0.000000 1.027029
v 0.059356 0.000000 0.915875
v 0.067463 0.000000 0.911919
v 0.031444 0.000000 1.049295
v 0.104116 0.000000 1.075315
v 0.090750 0.000000 1.032046
v 0.097406 0.000000 1.053659
v 0.093989 0.000000 1.042852
v 0.100820 0.000000 1.064464
v 0.070969 0.000000 0.810152
v -0.066422 0.000000 0.957668
v -0.066009 0.000000 0.970947
v -0.066752 0.000000 0.947005
v -0.064637 0.000000 1.015059
v -0.063799 0.000000 1.041979
v -0.065129 0.000000 0.999248
v -0.065544 0.000000 0.985873
v -0.062879 0.000000 1.071483
v -0.071022 0.000000 0.810152
v -0.067331 0.000000 0.928074
v -0.067037 0.000000 0.937684
v -0.067687 0.000000 0.916119
v -0.058629 0.000000 1.170966
v 0.061365 0.000000 1.087242
v 0.058787 0.000000 1.170966
v -0.062466 0.000000 1.084791
v 0.000103 0.000000 1.170966
v -0.000052 0.000000 0.810152
v 0.048683 0.011850 0.919647
v 0.040323 0.011427 0.924345
v 0.043881 0.023733 0.919249
v 0.035066 0.022863 0.923760
v 0.036447 0.034912 0.918735
v 0.027368 0.033178 0.923052
v 0.027182 0.044467 0.917992
v 0.017655 0.042060 0.922047
v 0.015937 0.052253 0.917108
v 0.006485 0.048942 0.920907
v 0.003630 0.057984 0.916052
v -0.005705 0.054223 0.919449
v -0.008008 0.061368 0.915002
v -0.017775 0.057691 0.917873
v -0.020257 0.063342 0.913570
v -0.029350 0.059718 0.916145
v -0.025420 0.053097 0.922815
v -0.037213 0.055068 0.920849
v -0.013628 0.049981 0.924486
v -0.001539 0.045498 0.925906
v 0.009710 0.039218 0.927253
v 0.019383 0.031190 0.928420
v 0.027238 0.021710 0.929157
v 0.032670 0.010890 0.929816
v -0.043014 0.050470 0.928101
v -0.031347 0.048626 0.929709
v -0.019544 0.045917 0.931180
v -0.007724 0.041938 0.932584
v 0.012818 0.029427 0.934748
v 0.003274 0.036535 0.933733
v 0.020513 0.020741 0.935423
v 0.025908 0.010638 0.935963
v -0.046753 0.046702 0.937613
v -0.034628 0.045139 0.938351
v -0.047894 0.045084 0.947043
v -0.036466 0.043169 0.947719
v -0.023438 0.042679 0.939337
v -0.011944 0.039223 0.940368
v -0.001280 0.034489 0.941107
v -0.025427 0.040805 0.948353
v -0.014322 0.037634 0.948877
v -0.004008 0.033271 0.949262
v 0.004749 0.027344 0.949618
v 0.007952 0.028072 0.941894
v 0.011610 0.019607 0.949880
v 0.015283 0.019972 0.942414
v 0.016232 0.010170 0.949925
v 0.020360 0.010345 0.942752
v -0.026223 0.039424 0.969930
v -0.026214 0.039924 0.957650
v -0.047845 0.044521 0.957708
v -0.047532 0.044207 0.970987
v -0.015613 0.037057 0.957593
v -0.015959 0.036628 0.969023
v -0.036606 0.041732 0.970504
v -0.036836 0.042304 0.957712
v -0.006338 0.032780 0.968185
v -0.005301 0.032764 0.957678
v 0.001965 0.027262 0.967342
v 0.002963 0.027198 0.957649
v 0.008191 0.019847 0.966555
v 0.009332 0.019721 0.957568
v 0.012001 0.010393 0.965785
v 0.013348 0.010250 0.957566
v -0.025311 0.038676 1.010762
v -0.046385 0.043177 1.015095
v -0.045702 0.042530 1.042014
v -0.023943 0.038210 1.037706
v -0.012648 0.035644 1.035664
v -0.014734 0.036040 1.008705
v -0.001642 0.032364 1.033432
v -0.004625 0.032488 1.006612
v 0.008312 0.027674 1.031106
v 0.004393 0.027485 1.004657
v 0.017190 0.020666 1.028987
v 0.011815 0.020352 1.002510
v 0.023256 0.011080 1.027493
v 0.016626 0.010823 1.000808
v 0.013723 0.010725 0.987400
v 0.009478 0.020209 0.988863
v 0.002618 0.027521 0.990535
v -0.005809 0.032617 0.992411
v -0.015494 0.036217 0.994105
v -0.025908 0.038917 0.996147
v -0.046752 0.043529 0.999286
v -0.046963 0.043809 0.985912
v -0.026411 0.039139 0.983060
v -0.016083 0.036382 0.981368
v -0.006646 0.032726 0.979994
v 0.001779 0.027409 0.978368
v 0.008205 0.020065 0.976951
v 0.012140 0.010526 0.975696
v -0.034666 0.040454 1.039861
v -0.035586 0.040878 1.012859
v -0.036040 0.041218 0.997670
v -0.036514 0.041444 0.984508
v 0.002201 0.064135 0.913298
v -0.009592 0.065563 0.912118
v 0.013512 0.060660 0.913915
v 0.026053 0.054595 0.914459
v 0.037065 0.046269 0.914930
v 0.046222 0.036023 0.915289
v 0.053095 0.024261 0.915555
v 0.057520 0.011933 0.915682
v 0.066338 0.011799 0.911920
v 0.062678 0.024365 0.911920
v 0.056191 0.036571 0.911920
v 0.047464 0.047375 0.911920
v 0.035768 0.056473 0.911920
v 0.022139 0.062860 0.911919
v 0.009923 0.065884 0.911920
v -0.044955 0.041830 1.071517
v -0.035030 0.040000 1.068630
v -0.022775 0.039117 1.065066
v 0.028688 0.011485 1.050097
v 0.021547 0.021196 1.052174
v 0.011627 0.027786 1.055059
v 0.000465 0.032308 1.058306
v -0.011220 0.037525 1.061705
v -0.040712 0.044758 1.099082
v -0.035812 0.048378 1.105458
v -0.028366 0.039699 1.066692
v -0.028267 0.052614 1.108488
v -0.018746 0.056934 1.109720
v -0.016649 0.038469 1.063284
v -0.008138 0.059429 1.107713
v -0.005129 0.036554 1.059933
v 0.000158 0.060113 1.105512
v 0.020375 0.031440 1.052515
v 0.012758 0.032807 1.054730
v 0.021680 0.056336 1.099411
v 0.032757 0.050803 1.095702
v 0.014788 0.058440 1.101415
v 0.006287 0.034199 1.056612
v 0.000815 0.035430 1.058204
v 0.007132 0.059776 1.103530
v 0.044427 0.041671 1.091967
v 0.029318 0.030088 1.049914
v 0.052406 0.036621 1.089742
v 0.039162 0.029030 1.047050
v 0.062145 0.031077 1.087025
v 0.048831 0.028530 1.044238
v 0.069458 0.028958 1.084984
v 0.056794 0.028549 1.041922
v 0.062910 0.028639 1.040143
v 0.074725 0.028638 1.083515
v 0.079945 0.028303 1.082058
v 0.067736 0.028324 1.038740
v 0.084525 0.027235 1.080781
v 0.072123 0.027313 1.037464
v 0.088396 0.025605 1.079701
v 0.076200 0.025498 1.036278
v 0.091831 0.023521 1.078743
v 0.079563 0.023541 1.035300
v 0.095280 0.020652 1.077780
v 0.083130 0.020669 1.034262
v 0.098265 0.017251 1.076947
v 0.086160 0.017211 1.033381
v 0.100598 0.013593 1.076297
v 0.088441 0.013612 1.032717
v 0.102481 0.009391 1.075771
v 0.089790 0.009484 1.032325
v 0.103627 0.005304 1.075452
v 0.090538 0.004955 1.032107
v -0.044643 0.041614 1.084793
v -0.040051 0.041303 1.070091
v -0.011165 0.035348 1.061689
v -0.040148 0.040949 1.070119
v -0.040277 0.041525 1.041010
v -0.041093 0.042046 1.013978
v -0.041525 0.042403 0.998521
v -0.041842 0.042655 0.985195
v -0.042204 0.042995 0.970791
v -0.042497 0.043488 0.957905
v -0.042363 0.044241 0.947404
v -0.040859 0.046143 0.937946
v -0.037152 0.049697 0.929080
v -0.031475 0.054210 0.921936
v -0.023555 0.058673 0.917324
v -0.014323 0.062508 0.914407
v -0.004072 0.065268 0.912629
v -0.035018 0.040467 1.068627
v -0.023078 0.037798 1.065153
v -0.041691 0.041782 1.077532
v -0.037397 0.042233 1.083126
v -0.031655 0.043411 1.086093
v -0.025088 0.045050 1.086912
v -0.017391 0.046891 1.086741
v -0.009400 0.047710 1.085061
v -0.002432 0.047617 1.082979
v 0.004036 0.046988 1.081078
v 0.010418 0.045839 1.079179
v 0.017235 0.044065 1.077168
v 0.026669 0.040655 1.074380
v 0.036892 0.036123 1.070847
v 0.045886 0.032602 1.068235
v 0.054902 0.030025 1.065698
v 0.061962 0.028993 1.063664
v 0.067955 0.028597 1.061921
v 0.073192 0.027963 1.060415
v 0.077786 0.026819 1.059096
v 0.081832 0.025282 1.057922
v 0.085609 0.022952 1.056876
v 0.088902 0.020164 1.055978
v 0.091735 0.016868 1.055235
v 0.094029 0.013193 1.054651
v 0.095736 0.009192 1.054196
v 0.096888 0.004970 1.053846
v 0.093560 0.004867 1.042961
v 0.092554 0.009195 1.043355
v 0.091094 0.013261 1.043793
v 0.088814 0.016873 1.044436
v 0.085943 0.020143 1.045252
v 0.082604 0.022862 1.046207
v 0.079067 0.025114 1.047248
v 0.074952 0.026786 1.048415
v 0.070595 0.028192 1.049674
v 0.065528 0.028606 1.051136
v 0.059395 0.028750 1.052909
v 0.051809 0.029243 1.055098
v 0.042626 0.030689 1.057732
v 0.033245 0.032915 1.060486
v 0.023646 0.035753 1.063618
v 0.015201 0.038149 1.066086
v 0.008509 0.039730 1.068061
v 0.002513 0.040945 1.069807
v -0.003655 0.041816 1.071609
v -0.010097 0.042252 1.073592
v -0.016884 0.042279 1.075247
v -0.023713 0.041736 1.076099
v -0.029934 0.041343 1.076470
v -0.035989 0.041249 1.075932
v -0.040769 0.041460 1.073782
v -0.042618 0.042120 1.081278
v -0.038903 0.043413 1.090363
v -0.033517 0.045851 1.095574
v -0.026550 0.048735 1.097629
v -0.018010 0.051688 1.098064
v -0.008777 0.053414 1.096381
v -0.001233 0.053700 1.094200
v 0.005553 0.053274 1.092217
v 0.012330 0.052111 1.090221
v 0.019358 0.050059 1.088165
v 0.029699 0.045687 1.085154
v 0.040575 0.039286 1.081204
v 0.049247 0.034571 1.078693
v 0.058422 0.030742 1.076169
v 0.065347 0.029172 1.074177
v 0.071101 0.028665 1.072478
v 0.076420 0.028216 1.070970
v 0.081003 0.027152 1.069666
v 0.085047 0.025389 1.068501
v 0.088735 0.023239 1.067486
v 0.092029 0.020367 1.066620
v 0.094901 0.017019 1.065927
v 0.097284 0.013339 1.065374
v 0.099174 0.009323 1.064928
v 0.100386 0.005159 1.064591
v 0.069740 0.012474 0.810152
v 0.065740 0.025758 0.810152
v 0.058651 0.038661 0.810152
v 0.049115 0.050084 0.810152
v 0.036335 0.059701 0.810152
v 0.021441 0.066454 0.810152
v 0.008092 0.069651 0.810152
v -0.013011 0.069234 0.810152
v -0.058708 0.028247 0.957708
v -0.058235 0.028194 0.970987
v -0.059055 0.028365 0.947043
v -0.056655 0.028042 1.015095
v -0.055701 0.027926 1.042015
v -0.057214 0.028113 0.999286
v -0.057671 0.028209 0.985912
v -0.054624 0.027870 1.071516
v -0.062565 0.019468 0.957708
v -0.062089 0.019423 0.970987
v -0.062926 0.019554 0.947043
v -0.060504 0.019285 1.015095
v -0.059542 0.019186 1.042015
v -0.061065 0.019349 0.999286
v -0.061530 0.019427 0.985912
v -0.058462 0.019138 1.071516
v -0.065207 0.009914 0.957708
v -0.064755 0.009844 0.970987
v -0.065565 0.009969 0.947043
v -0.063294 0.009620 1.015095
v -0.062501 0.009499 1.042015
v -0.063788 0.009696 0.999286
v -0.064240 0.009766 0.985912
v -0.061642 0.009367 1.071516
v -0.050063 0.035115 1.071515
v -0.051054 0.035474 1.042013
v -0.051905 0.035874 1.015095
v -0.052404 0.036110 0.999286
v -0.052801 0.036341 0.985912
v -0.053321 0.036498 0.970987
v -0.053740 0.036697 0.957708
v -0.053940 0.037038 0.947043
v -0.052474 0.046860 0.810152
v -0.058527 0.038820 0.810152
v -0.063503 0.030042 0.810152
v -0.067374 0.021231 0.810152
v -0.070032 0.010657 0.810152
v -0.048533 0.045332 0.928099
v -0.054581 0.037288 0.928101
v -0.059675 0.028599 0.928103
v -0.063546 0.019788 0.928103
v -0.066188 0.010065 0.928103
v -0.048204 0.045204 0.937716
v -0.054251 0.037160 0.937712
v -0.059356 0.028479 0.937719
v -0.063227 0.019668 0.937719
v -0.065868 0.010016 0.937719
v -0.048801 0.045436 0.916145
v -0.054850 0.037392 0.916146
v -0.059936 0.028698 0.916147
v -0.063807 0.019886 0.916147
v -0.066450 0.010105 0.916147
v -0.023039 0.066319 0.810152
v -0.032424 0.061921 0.810152
v -0.037487 0.055019 0.916143
v -0.040956 0.056952 0.810152
v -0.043400 0.050526 0.916144
v -0.046843 0.052055 0.810152
v 0.000893 0.066857 0.911920
v -0.001776 0.070623 0.810152
v -0.042316 0.039634 1.170966
v -0.046212 0.034626 1.170966
v -0.051142 0.027551 1.170966
v -0.055014 0.018735 1.170966
v -0.058086 0.008821 1.170966
v 0.038937 0.046542 1.093448
v 0.035154 0.042527 1.083158
v 0.031777 0.038377 1.072619
v 0.028430 0.034241 1.062090
v 0.024759 0.030612 1.051240
v 0.016479 0.032146 1.053648
v 0.019417 0.036901 1.064876
v 0.021969 0.042443 1.075729
v 0.024560 0.047996 1.086589
v 0.027407 0.053878 1.097584
v -0.027296 0.050672 1.170966
v -0.018232 0.054757 1.170966
v -0.007623 0.057257 1.170966
v 0.000254 0.057477 1.170966
v 0.020819 0.053985 1.170966
v 0.026116 0.051342 1.170966
v 0.
gitextract_6orlelw8/
├── .github/
│ └── workflows/
│ └── build.yaml
├── .gitignore
├── .pre-commit-config.yaml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bigym/
│ ├── __init__.py
│ ├── action_modes.py
│ ├── bigym_env.py
│ ├── bigym_renderer.py
│ ├── const.py
│ ├── envs/
│ │ ├── __init__.py
│ │ ├── cupboards.py
│ │ ├── dishwasher.py
│ │ ├── dishwasher_cups.py
│ │ ├── dishwasher_cutlery.py
│ │ ├── dishwasher_plates.py
│ │ ├── groceries.py
│ │ ├── manipulation.py
│ │ ├── move_plates.py
│ │ ├── pick_and_place.py
│ │ ├── presets/
│ │ │ ├── cabinet.yaml
│ │ │ ├── cabinet_door.yaml
│ │ │ ├── cabinet_hob.yaml
│ │ │ ├── counter_base_2.yaml
│ │ │ ├── counter_base_2_hob.yaml
│ │ │ ├── counter_base_wall_1x1.yaml
│ │ │ ├── counter_base_wall_2x2.yaml
│ │ │ ├── counter_base_wall_3x1.yaml
│ │ │ ├── counter_dishwasher.yaml
│ │ │ ├── counter_dishwasher_cutlery_cabinet.yaml
│ │ │ ├── counter_dishwasher_wall_cabinet.yaml
│ │ │ ├── dishwasher.yaml
│ │ │ ├── move_plates.yaml
│ │ │ └── stack_blocks.yaml
│ │ ├── props/
│ │ │ ├── __init__.py
│ │ │ ├── cabintets.py
│ │ │ ├── cutlery.py
│ │ │ ├── dishwasher.py
│ │ │ ├── holders.py
│ │ │ ├── items.py
│ │ │ ├── kitchenware.py
│ │ │ ├── preset.py
│ │ │ ├── prop.py
│ │ │ └── tables.py
│ │ ├── reach_target.py
│ │ └── xmls/
│ │ ├── 3D_MODELS_ATTRIBUTION.md
│ │ ├── google_robot/
│ │ │ ├── assets/
│ │ │ │ ├── link_base_0_00.stl
│ │ │ │ ├── link_base_0_01.stl
│ │ │ │ ├── link_base_1_00.stl
│ │ │ │ ├── link_base_1_01.stl
│ │ │ │ ├── link_base_1_02.stl
│ │ │ │ ├── link_base_1_03.stl
│ │ │ │ ├── link_base_1_04.stl
│ │ │ │ ├── link_base_1_05.stl
│ │ │ │ ├── link_base_1_06.stl
│ │ │ │ ├── link_base_1_07.stl
│ │ │ │ ├── link_base_1_08.stl
│ │ │ │ ├── link_base_1_09.stl
│ │ │ │ ├── link_base_1_10.stl
│ │ │ │ ├── link_base_1_11.stl
│ │ │ │ ├── link_base_1_12.stl
│ │ │ │ ├── link_base_1_13.stl
│ │ │ │ ├── link_base_1_14.stl
│ │ │ │ ├── link_base_1_15.stl
│ │ │ │ ├── link_base_1_16.stl
│ │ │ │ ├── link_base_1_17.stl
│ │ │ │ ├── link_base_1_18.stl
│ │ │ │ ├── link_base_1_19.stl
│ │ │ │ ├── link_base_v.obj
│ │ │ │ ├── link_bicep.stl
│ │ │ │ ├── link_bicep_v.obj
│ │ │ │ ├── link_elbow.stl
│ │ │ │ ├── link_elbow_v.obj
│ │ │ │ ├── link_finger_base.stl
│ │ │ │ ├── link_finger_base_v.obj
│ │ │ │ ├── link_finger_tip.stl
│ │ │ │ ├── link_finger_tip_v.obj
│ │ │ │ ├── link_forearm.stl
│ │ │ │ ├── link_forearm_v.obj
│ │ │ │ ├── link_gripper.stl
│ │ │ │ ├── link_gripper_v.obj
│ │ │ │ ├── link_head_pan.stl
│ │ │ │ ├── link_head_pan_v.obj
│ │ │ │ ├── link_head_tilt.stl
│ │ │ │ ├── link_head_tilt_v.obj
│ │ │ │ ├── link_shoulder.stl
│ │ │ │ ├── link_shoulder_v.obj
│ │ │ │ ├── link_torso_00.stl
│ │ │ │ ├── link_torso_01.stl
│ │ │ │ ├── link_torso_v.obj
│ │ │ │ ├── link_wheel_v.obj
│ │ │ │ ├── link_wrist.stl
│ │ │ │ └── link_wrist_v.obj
│ │ │ ├── robot.xml
│ │ │ └── scene.xml
│ │ ├── h1/
│ │ │ ├── assets/
│ │ │ │ ├── left_ankle_link.stl
│ │ │ │ ├── left_elbow_link.stl
│ │ │ │ ├── left_hip_pitch_link.stl
│ │ │ │ ├── left_hip_roll_link.stl
│ │ │ │ ├── left_hip_yaw_link.stl
│ │ │ │ ├── left_knee_link.stl
│ │ │ │ ├── left_shoulder_pitch_link.stl
│ │ │ │ ├── left_shoulder_roll_link.stl
│ │ │ │ ├── left_shoulder_yaw_link.stl
│ │ │ │ ├── logo_link.stl
│ │ │ │ ├── pelvis.stl
│ │ │ │ ├── right_ankle_link.stl
│ │ │ │ ├── right_elbow_link.stl
│ │ │ │ ├── right_hip_pitch_link.stl
│ │ │ │ ├── right_hip_roll_link.stl
│ │ │ │ ├── right_hip_yaw_link.stl
│ │ │ │ ├── right_knee_link.stl
│ │ │ │ ├── right_shoulder_pitch_link.stl
│ │ │ │ ├── right_shoulder_roll_link.stl
│ │ │ │ ├── right_shoulder_yaw_link.stl
│ │ │ │ └── torso_link.stl
│ │ │ ├── h1.xml
│ │ │ └── h1_floating_base.xml
│ │ ├── hello_robot_stretch/
│ │ │ ├── assets/
│ │ │ │ ├── base_link_0.obj
│ │ │ │ ├── base_link_1.obj
│ │ │ │ ├── base_link_2.obj
│ │ │ │ ├── base_link_3.obj
│ │ │ │ ├── base_link_4.obj
│ │ │ │ ├── base_link_5.obj
│ │ │ │ ├── base_link_6.obj
│ │ │ │ ├── base_link_7.obj
│ │ │ │ ├── base_link_8.obj
│ │ │ │ ├── base_link_casterless.stl
│ │ │ │ ├── laser.obj
│ │ │ │ ├── link_arm_l0_0.obj
│ │ │ │ ├── link_arm_l0_1.obj
│ │ │ │ ├── link_arm_l0_2.obj
│ │ │ │ ├── link_arm_l1_0.obj
│ │ │ │ ├── link_arm_l1_1.obj
│ │ │ │ ├── link_arm_l2_0.obj
│ │ │ │ ├── link_arm_l2_1.obj
│ │ │ │ ├── link_arm_l3_0.obj
│ │ │ │ ├── link_arm_l3_1.obj
│ │ │ │ ├── link_arm_l4_0.obj
│ │ │ │ ├── link_arm_l4_1.obj
│ │ │ │ ├── link_aruco_inner_wrist.obj
│ │ │ │ ├── link_aruco_left_base.obj
│ │ │ │ ├── link_aruco_right_base.obj
│ │ │ │ ├── link_aruco_shoulder.obj
│ │ │ │ ├── link_aruco_top_wrist.obj
│ │ │ │ ├── link_gripper_0.obj
│ │ │ │ ├── link_gripper_1.obj
│ │ │ │ ├── link_gripper_finger_left_0.obj
│ │ │ │ ├── link_gripper_finger_left_1.obj
│ │ │ │ ├── link_gripper_finger_right_0.obj
│ │ │ │ ├── link_gripper_finger_right_1.obj
│ │ │ │ ├── link_gripper_fingertip_left.stl
│ │ │ │ ├── link_gripper_fingertip_right.stl
│ │ │ │ ├── link_head_0.obj
│ │ │ │ ├── link_head_1.obj
│ │ │ │ ├── link_head_10.obj
│ │ │ │ ├── link_head_11.obj
│ │ │ │ ├── link_head_2.obj
│ │ │ │ ├── link_head_3.obj
│ │ │ │ ├── link_head_4.obj
│ │ │ │ ├── link_head_5.obj
│ │ │ │ ├── link_head_6.obj
│ │ │ │ ├── link_head_7.obj
│ │ │ │ ├── link_head_8.obj
│ │ │ │ ├── link_head_9.obj
│ │ │ │ ├── link_head_pan_0.obj
│ │ │ │ ├── link_head_pan_1.obj
│ │ │ │ ├── link_head_tilt_0.obj
│ │ │ │ ├── link_head_tilt_1.obj
│ │ │ │ ├── link_left_wheel_0.obj
│ │ │ │ ├── link_left_wheel_1.obj
│ │ │ │ ├── link_lift_0.obj
│ │ │ │ ├── link_lift_1.obj
│ │ │ │ ├── link_lift_2.obj
│ │ │ │ ├── link_lift_3.obj
│ │ │ │ ├── link_lift_4.obj
│ │ │ │ ├── link_lift_5.obj
│ │ │ │ ├── link_lift_6.obj
│ │ │ │ ├── link_lift_7.obj
│ │ │ │ ├── link_lift_8.obj
│ │ │ │ ├── link_lift_9.obj
│ │ │ │ ├── link_mast.obj
│ │ │ │ ├── link_right_wheel_0.obj
│ │ │ │ ├── link_right_wheel_1.obj
│ │ │ │ ├── link_wrist_yaw.obj
│ │ │ │ └── respeaker_base.obj
│ │ │ ├── scene.xml
│ │ │ └── stretch.xml
│ │ ├── props/
│ │ │ ├── board/
│ │ │ │ ├── assets/
│ │ │ │ │ └── board.obj
│ │ │ │ └── board.xml
│ │ │ ├── box/
│ │ │ │ ├── assets/
│ │ │ │ │ └── box.obj
│ │ │ │ └── box.xml
│ │ │ ├── cube/
│ │ │ │ └── cube.xml
│ │ │ ├── cutlery/
│ │ │ │ ├── fork/
│ │ │ │ │ ├── assets/
│ │ │ │ │ │ ├── fork.obj
│ │ │ │ │ │ ├── fork_collision_001.obj
│ │ │ │ │ │ └── fork_collision_002.obj
│ │ │ │ │ ├── fork.xml
│ │ │ │ │ └── fork_convex.xml
│ │ │ │ ├── knife/
│ │ │ │ │ ├── assets/
│ │ │ │ │ │ ├── knife.obj
│ │ │ │ │ │ ├── knife_collision_001.obj
│ │ │ │ │ │ └── knife_collision_002.obj
│ │ │ │ │ ├── knife.xml
│ │ │ │ │ └── knife_convex.xml
│ │ │ │ └── spoon/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── spoon.obj
│ │ │ │ │ ├── spoon_collision_001.obj
│ │ │ │ │ └── spoon_collision_002.obj
│ │ │ │ ├── spoon.xml
│ │ │ │ └── spoon_convex.xml
│ │ │ ├── cutlery_tray/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── cutlery_tray.obj
│ │ │ │ │ ├── cutlery_tray_collision_001.obj
│ │ │ │ │ ├── cutlery_tray_collision_002.obj
│ │ │ │ │ ├── cutlery_tray_collision_003.obj
│ │ │ │ │ ├── cutlery_tray_collision_004.obj
│ │ │ │ │ ├── cutlery_tray_collision_005.obj
│ │ │ │ │ ├── cutlery_tray_collision_006.obj
│ │ │ │ │ ├── cutlery_tray_collision_007.obj
│ │ │ │ │ ├── cutlery_tray_collision_008.obj
│ │ │ │ │ ├── cutlery_tray_collision_009.obj
│ │ │ │ │ ├── cutlery_tray_collision_010.obj
│ │ │ │ │ └── cutlery_tray_collision_011.obj
│ │ │ │ └── cutlery_tray.xml
│ │ │ ├── dish_drainer/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── rack.obj
│ │ │ │ │ ├── rack_collision_001.obj
│ │ │ │ │ ├── rack_collision_002.obj
│ │ │ │ │ ├── rack_collision_003.obj
│ │ │ │ │ ├── rack_collision_004.obj
│ │ │ │ │ ├── rack_collision_005.obj
│ │ │ │ │ ├── rack_collision_006.obj
│ │ │ │ │ ├── rack_collision_007.obj
│ │ │ │ │ ├── rack_collision_008.obj
│ │ │ │ │ ├── rack_collision_009.obj
│ │ │ │ │ ├── rack_collision_010.obj
│ │ │ │ │ ├── rack_collision_011.obj
│ │ │ │ │ ├── rack_collision_012.obj
│ │ │ │ │ ├── rack_collision_013.obj
│ │ │ │ │ ├── rack_collision_014.obj
│ │ │ │ │ ├── rack_collision_015.obj
│ │ │ │ │ ├── rack_collision_016.obj
│ │ │ │ │ ├── rack_collision_017.obj
│ │ │ │ │ └── rack_collision_018.obj
│ │ │ │ └── dish_drainer.xml
│ │ │ ├── dishwasher/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── collision/
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_001.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_002.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_003.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_004.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_005.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_006.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_007.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_008.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_009.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_010.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_011.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_012.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_013.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_014.obj
│ │ │ │ │ │ ├── collision_dish_washer_bottom_basket_015.obj
│ │ │ │ │ │ ├── collision_dish_washer_mid_sprinkle.obj
│ │ │ │ │ │ ├── collision_door_001.obj
│ │ │ │ │ │ ├── collision_door_003.obj
│ │ │ │ │ │ ├── collision_door_004.obj
│ │ │ │ │ │ ├── collision_door_006.obj
│ │ │ │ │ │ ├── collision_door_007.obj
│ │ │ │ │ │ ├── collision_door_008.obj
│ │ │ │ │ │ ├── collision_door_009.obj
│ │ │ │ │ │ ├── collision_holder_001.obj
│ │ │ │ │ │ ├── collision_holder_002.obj
│ │ │ │ │ │ ├── collision_holder_003.obj
│ │ │ │ │ │ ├── collision_holder_004.obj
│ │ │ │ │ │ ├── collision_holder_005.obj
│ │ │ │ │ │ ├── collision_holder_006.obj
│ │ │ │ │ │ ├── collision_holder_007.obj
│ │ │ │ │ │ ├── collision_holder_008.obj
│ │ │ │ │ │ ├── collision_holder_009.obj
│ │ │ │ │ │ ├── collision_holder_010.obj
│ │ │ │ │ │ ├── collision_holder_011.obj
│ │ │ │ │ │ ├── collision_holder_012.obj
│ │ │ │ │ │ ├── collision_holder_013.obj
│ │ │ │ │ │ ├── collision_holder_014.obj
│ │ │ │ │ │ ├── collision_tray_001.obj
│ │ │ │ │ │ ├── collision_tray_002.obj
│ │ │ │ │ │ ├── collision_tray_003.obj
│ │ │ │ │ │ ├── collision_tray_004.obj
│ │ │ │ │ │ ├── collision_tray_005.obj
│ │ │ │ │ │ ├── collision_tray_006.obj
│ │ │ │ │ │ ├── collision_tray_007.obj
│ │ │ │ │ │ ├── collision_tray_008.obj
│ │ │ │ │ │ ├── collision_tray_009.obj
│ │ │ │ │ │ ├── collision_tray_010.obj
│ │ │ │ │ │ ├── collision_tray_011.obj
│ │ │ │ │ │ ├── collision_tray_012.obj
│ │ │ │ │ │ ├── collision_tray_013.obj
│ │ │ │ │ │ ├── collision_tray_014.obj
│ │ │ │ │ │ ├── collision_tray_015.obj
│ │ │ │ │ │ ├── collision_tray_016.obj
│ │ │ │ │ │ ├── collision_tray_017.obj
│ │ │ │ │ │ ├── collision_tray_018.obj
│ │ │ │ │ │ ├── collision_tray_019.obj
│ │ │ │ │ │ ├── collision_tray_020.obj
│ │ │ │ │ │ ├── collision_tray_021.obj
│ │ │ │ │ │ ├── collision_tray_022.obj
│ │ │ │ │ │ ├── collision_tray_023.obj
│ │ │ │ │ │ ├── collision_tray_024.obj
│ │ │ │ │ │ ├── collision_tray_025.obj
│ │ │ │ │ │ ├── collision_tray_026.obj
│ │ │ │ │ │ ├── collision_tray_027.obj
│ │ │ │ │ │ ├── collision_tray_028.obj
│ │ │ │ │ │ ├── collision_tray_029.obj
│ │ │ │ │ │ ├── collision_tray_030.obj
│ │ │ │ │ │ ├── collision_tray_031.obj
│ │ │ │ │ │ ├── collision_tray_032.obj
│ │ │ │ │ │ ├── collision_tray_033.obj
│ │ │ │ │ │ ├── collision_tray_mid_001.obj
│ │ │ │ │ │ ├── collision_tray_mid_002.obj
│ │ │ │ │ │ ├── collision_tray_mid_003.obj
│ │ │ │ │ │ ├── collision_tray_mid_004.obj
│ │ │ │ │ │ ├── collision_tray_mid_005.obj
│ │ │ │ │ │ ├── collision_tray_mid_006.obj
│ │ │ │ │ │ ├── collision_tray_mid_007.obj
│ │ │ │ │ │ ├── collision_tray_mid_008.obj
│ │ │ │ │ │ ├── collision_tray_mid_009.obj
│ │ │ │ │ │ ├── collision_tray_mid_010.obj
│ │ │ │ │ │ ├── collision_tray_mid_011.obj
│ │ │ │ │ │ ├── collision_tray_mid_012.obj
│ │ │ │ │ │ ├── collision_tray_mid_013.obj
│ │ │ │ │ │ ├── collision_tray_mid_014.obj
│ │ │ │ │ │ ├── collision_tray_mid_015.obj
│ │ │ │ │ │ ├── collision_tray_mid_016.obj
│ │ │ │ │ │ ├── collision_tray_mid_017.obj
│ │ │ │ │ │ ├── collision_tray_mid_018.obj
│ │ │ │ │ │ ├── collision_tray_mid_019.obj
│ │ │ │ │ │ ├── collision_tray_mid_020.obj
│ │ │ │ │ │ ├── collision_tray_mid_021.obj
│ │ │ │ │ │ ├── collision_tray_mid_022.obj
│ │ │ │ │ │ ├── collision_tray_mid_023.obj
│ │ │ │ │ │ ├── collision_tray_mid_024.obj
│ │ │ │ │ │ ├── collision_tray_mid_025.obj
│ │ │ │ │ │ ├── collision_tray_mid_026.obj
│ │ │ │ │ │ ├── collision_tray_mid_027.obj
│ │ │ │ │ │ └── collision_tray_mid_plates_holder.obj
│ │ │ │ │ └── visual/
│ │ │ │ │ ├── dish_washer_body_001.obj
│ │ │ │ │ ├── dish_washer_bottom_001.obj
│ │ │ │ │ ├── dish_washer_bottom_cuttlery_basket_001.obj
│ │ │ │ │ ├── dish_washer_bottom_plates_holder_001.obj
│ │ │ │ │ ├── dish_washer_bottom_wheel.obj
│ │ │ │ │ ├── dish_washer_door_001.obj
│ │ │ │ │ ├── dish_washer_mid_001.obj
│ │ │ │ │ ├── dish_washer_mid_sprinkle.obj
│ │ │ │ │ └── dish_washer_top_001.obj
│ │ │ │ └── dishwasher.xml
│ │ │ ├── groceries/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── beer.obj
│ │ │ │ │ ├── cereal.obj
│ │ │ │ │ ├── crisps.obj
│ │ │ │ │ ├── ketchup.obj
│ │ │ │ │ ├── mustard.obj
│ │ │ │ │ └── soda.obj
│ │ │ │ ├── beer.xml
│ │ │ │ ├── cereal.xml
│ │ │ │ ├── crisps.xml
│ │ │ │ ├── detergent/
│ │ │ │ │ ├── assets/
│ │ │ │ │ │ ├── detergent.obj
│ │ │ │ │ │ ├── detergent_collision_001.obj
│ │ │ │ │ │ └── detergent_collision_002.obj
│ │ │ │ │ └── detergent.xml
│ │ │ │ ├── ketchup.xml
│ │ │ │ ├── mustard.xml
│ │ │ │ ├── soap/
│ │ │ │ │ ├── assets/
│ │ │ │ │ │ ├── soap.obj
│ │ │ │ │ │ ├── soap_collision_001.obj
│ │ │ │ │ │ └── soap_collision_002.obj
│ │ │ │ │ └── soap.xml
│ │ │ │ ├── soda.xml
│ │ │ │ └── wine/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── wine_bottle.obj
│ │ │ │ │ ├── wine_bottle_collision_001.obj
│ │ │ │ │ └── wine_bottle_collision_002.obj
│ │ │ │ └── wine.xml
│ │ │ ├── kitchen/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── drawer_600_full.obj
│ │ │ │ │ ├── drawer_600_half.obj
│ │ │ │ │ ├── drawer_600_quarter.obj
│ │ │ │ │ ├── drawer_handle.obj
│ │ │ │ │ ├── hanging_drawer_600.obj
│ │ │ │ │ └── hanging_drawer_600_glass.obj
│ │ │ │ ├── base_cabinet_600.xml
│ │ │ │ ├── open_shelf_600.xml
│ │ │ │ └── wall_cabinet_600.xml
│ │ │ ├── mug/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── mug.obj
│ │ │ │ │ ├── mug_collision_001.obj
│ │ │ │ │ ├── mug_collision_002.obj
│ │ │ │ │ ├── mug_collision_003.obj
│ │ │ │ │ ├── mug_collision_004.obj
│ │ │ │ │ ├── mug_collision_005.obj
│ │ │ │ │ ├── mug_collision_006.obj
│ │ │ │ │ ├── mug_collision_007.obj
│ │ │ │ │ ├── mug_collision_008.obj
│ │ │ │ │ ├── mug_collision_009.obj
│ │ │ │ │ ├── mug_collision_010.obj
│ │ │ │ │ ├── mug_collision_011.obj
│ │ │ │ │ ├── mug_collision_012.obj
│ │ │ │ │ ├── mug_collision_013.obj
│ │ │ │ │ ├── mug_collision_014.obj
│ │ │ │ │ ├── mug_collision_015.obj
│ │ │ │ │ ├── mug_collision_016.obj
│ │ │ │ │ ├── mug_collision_017.obj
│ │ │ │ │ └── mug_collision_018.obj
│ │ │ │ └── mug.xml
│ │ │ ├── pan/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── pan.obj
│ │ │ │ │ ├── pan_collision_handle.obj
│ │ │ │ │ ├── pan_collision_handle_001.obj
│ │ │ │ │ └── pan_collision_handle_002.obj
│ │ │ │ ├── pan.xml
│ │ │ │ └── pan_orignal.xml
│ │ │ ├── plate/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── plate_01.obj
│ │ │ │ │ ├── plate_01_collision.obj
│ │ │ │ │ ├── plate_01_collision_001.obj
│ │ │ │ │ ├── plate_01_collision_002.obj
│ │ │ │ │ ├── plate_01_collision_003.obj
│ │ │ │ │ ├── plate_01_collision_004.obj
│ │ │ │ │ ├── plate_01_collision_005.obj
│ │ │ │ │ ├── plate_01_collision_006.obj
│ │ │ │ │ ├── plate_01_collision_007.obj
│ │ │ │ │ ├── plate_01_collision_008.obj
│ │ │ │ │ ├── plate_01_collision_009.obj
│ │ │ │ │ ├── plate_01_collision_010.obj
│ │ │ │ │ ├── plate_01_collision_011.obj
│ │ │ │ │ └── plate_01_collision_012.obj
│ │ │ │ ├── plate.xml
│ │ │ │ └── plate_convex.xml
│ │ │ ├── sandwich/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── bread.obj
│ │ │ │ │ ├── cheese.obj
│ │ │ │ │ ├── sandwich_collision.obj
│ │ │ │ │ ├── sandwich_collision_rounded.obj
│ │ │ │ │ └── tomatoes.obj
│ │ │ │ ├── sandwich.xml
│ │ │ │ └── sandwich_toasted.xml
│ │ │ ├── saucepan/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── saucepan.obj
│ │ │ │ │ └── saucepan_collision_handle.obj
│ │ │ │ ├── saucepan.xml
│ │ │ │ └── saucepan_original.xml
│ │ │ ├── spatula/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── spatula.obj
│ │ │ │ │ ├── spatula_collision_001.obj
│ │ │ │ │ └── spatula_collision_002.obj
│ │ │ │ └── spatula.xml
│ │ │ ├── table/
│ │ │ │ ├── assets/
│ │ │ │ │ ├── table.obj
│ │ │ │ │ ├── table_collision_001.obj
│ │ │ │ │ ├── table_collision_002.obj
│ │ │ │ │ ├── table_collision_003.obj
│ │ │ │ │ ├── table_collision_004.obj
│ │ │ │ │ ├── table_collision_005.obj
│ │ │ │ │ ├── table_collision_006.obj
│ │ │ │ │ ├── table_collision_007.obj
│ │ │ │ │ └── table_legs.obj
│ │ │ │ └── table.xml
│ │ │ └── table_dishwasher/
│ │ │ ├── assets/
│ │ │ │ ├── table_dishwasher.obj
│ │ │ │ ├── table_dishwasher_collision_001.obj
│ │ │ │ ├── table_dishwasher_collision_002.obj
│ │ │ │ ├── table_dishwasher_collision_003.obj
│ │ │ │ ├── table_dishwasher_collision_004.obj
│ │ │ │ ├── table_dishwasher_collision_005.obj
│ │ │ │ ├── table_dishwasher_collision_006.obj
│ │ │ │ └── table_dishwasher_legs.obj
│ │ │ └── table_dishwasher.xml
│ │ ├── robotiq_2f85/
│ │ │ ├── 2f85.xml
│ │ │ ├── 2f85_fine_manipulation.xml
│ │ │ └── assets/
│ │ │ ├── base.stl
│ │ │ ├── base_mount.stl
│ │ │ ├── coupler.stl
│ │ │ ├── driver.stl
│ │ │ ├── follower.stl
│ │ │ ├── pad.stl
│ │ │ ├── silicone_pad.stl
│ │ │ └── spring_link.stl
│ │ └── world.xml
│ ├── robots/
│ │ ├── __init__.py
│ │ ├── animated_legs.py
│ │ ├── config.py
│ │ ├── configs/
│ │ │ ├── __init__.py
│ │ │ ├── google_robot.py
│ │ │ ├── h1.py
│ │ │ ├── robotiq.py
│ │ │ └── stretch.py
│ │ ├── floating_base.py
│ │ ├── gripper.py
│ │ └── robot.py
│ └── utils/
│ ├── __init__.py
│ ├── callables_cache.py
│ ├── dof.py
│ ├── env_health.py
│ ├── env_utils.py
│ ├── observation_config.py
│ ├── physics_utils.py
│ ├── robot_highlighter.py
│ └── shared.py
├── demonstrations/
│ ├── __init__.py
│ ├── const.py
│ ├── demo.py
│ ├── demo_converter.py
│ ├── demo_player.py
│ ├── demo_recorder.py
│ ├── demo_store.py
│ └── utils.py
├── doc/
│ └── scripts/
│ ├── download_and_validate_demos.py
│ ├── download_demos.py
│ ├── measure_fps.py
│ ├── measure_fps_cams.py
│ ├── preview_renderer.py
│ ├── render_demos.py
│ └── render_previews.py
├── examples/
│ ├── launch_reach_target_pixels.py
│ ├── launch_reach_target_state.py
│ ├── record_and_replay_demo.py
│ └── replay_demo.py
├── setup.py
├── tests/
│ ├── __init__.py
│ ├── conftest.py
│ ├── data/
│ │ └── safetensors/
│ │ ├── 0_ReachTarget_JointPositionActionMode_state.safetensors
│ │ ├── 11_ReachTarget_TorqueActionMode_lightweight.safetensors
│ │ ├── 15_MovePlate_JointPositionActionMode_state.safetensors
│ │ ├── 17_MovePlate_JointPositionActionMode_pixel.safetensors
│ │ ├── 19_MovePlate_JointPositionActionMode_lightweight.safetensors
│ │ ├── 22_MovePlate_TorqueActionMode_state.safetensors
│ │ ├── 24_MovePlate_TorqueActionMode_pixel.safetensors
│ │ ├── 26_MovePlate_TorqueActionMode_lightweight.safetensors
│ │ ├── 2_ReachTarget_JointPositionActionMode_pixel.safetensors
│ │ ├── 30_StackBlocks_JointPositionActionMode_state.safetensors
│ │ ├── 32_StackBlocks_JointPositionActionMode_pixel.safetensors
│ │ ├── 34_StackBlocks_JointPositionActionMode_lightweight.safetensors
│ │ ├── 37_StackBlocks_TorqueActionMode_state.safetensors
│ │ ├── 39_StackBlocks_TorqueActionMode_pixel.safetensors
│ │ ├── 41_StackBlocks_TorqueActionMode_lightweight.safetensors
│ │ ├── 4_ReachTarget_JointPositionActionMode_lightweight.safetensors
│ │ ├── 7_ReachTarget_TorqueActionMode_state.safetensors
│ │ └── 9_ReachTarget_TorqueActionMode_pixel.safetensors
│ ├── pytest.ini
│ ├── tasks/
│ │ ├── test_move_plate.py
│ │ ├── test_stack_blocks.py
│ │ └── test_tasks.py
│ ├── test_action_modes.py
│ ├── test_demo_store.py
│ ├── test_demos.py
│ ├── test_envs.py
│ ├── test_observations.py
│ └── test_unstable_simulation.py
├── tools/
│ ├── __init__.py
│ ├── demo_player/
│ │ ├── __init__.py
│ │ ├── demo_converter_window.py
│ │ ├── demo_player_rendering.py
│ │ ├── demo_player_window.py
│ │ └── main.py
│ ├── demo_recorder/
│ │ ├── __init__.py
│ │ ├── demo_recorder_window.py
│ │ └── main.py
│ └── shared/
│ ├── __init__.py
│ ├── base_window.py
│ ├── primary_window.py
│ ├── settings_shelf.py
│ └── utils.py
└── vr/
├── Dockerfile
├── Makefile
├── README.md
├── __init__.py
├── disable_steamvr_windows.sh
├── docker-compose.yaml
├── ik/
│ ├── __init__.py
│ └── h1_upper_body_ik.py
├── pulse-client.conf
└── viewer/
├── __init__.py
├── control_profiles/
│ ├── __init__.py
│ ├── control_profile.py
│ ├── h1_floating.py
│ └── universal_floating.py
├── controller.py
├── full_screen_renderer.py
├── pyopenxr_to_mujoco_converter.py
├── vr_mujoco_renderer.py
├── vr_viewer.py
├── xmls/
│ ├── controller_left/
│ │ ├── assets/
│ │ │ └── controller.obj
│ │ └── controller_left.xml
│ └── controller_right/
│ ├── assets/
│ │ └── controller.obj
│ └── controller_right.xml
├── xr_context.py
└── xr_input.py
SYMBOL INDEX (811 symbols across 82 files)
FILE: bigym/action_modes.py
class TargetStateNotReachedWarning (line 24) | class TargetStateNotReachedWarning(Warning):
class PelvisDof (line 30) | class PelvisDof(Enum):
class ActionMode (line 42) | class ActionMode(ABC):
method __init__ (line 45) | def __init__(
method bind_robot (line 64) | def bind_robot(self, robot: Robot, mojo: Mojo):
method floating_base (line 70) | def floating_base(self) -> bool:
method floating_dofs (line 75) | def floating_dofs(self) -> list[PelvisDof]:
method action_space (line 80) | def action_space(
method step (line 87) | def step(self, action: np.ndarray):
method reset (line 97) | def reset(self, reset_state: np.ndarray):
class TorqueActionMode (line 105) | class TorqueActionMode(ActionMode):
method action_space (line 115) | def action_space(
method step (line 138) | def step(self, action: np.ndarray):
method reset (line 151) | def reset(self, reset_state: np.ndarray):
class JointPositionActionMode (line 173) | class JointPositionActionMode(ActionMode):
method __init__ (line 188) | def __init__(
method action_space (line 208) | def action_space(
method step (line 234) | def step(self, action: np.ndarray):
method reset (line 252) | def reset(self, reset_state: np.ndarray):
method _step_until_reached (line 282) | def _step_until_reached(self):
method _is_target_state_reached (line 296) | def _is_target_state_reached(self):
FILE: bigym/bigym_env.py
class BiGymEnv (line 34) | class BiGymEnv(gym.Env):
method __init__ (line 53) | def __init__(
method task_name (line 134) | def task_name(self) -> str:
method _use_pixels (line 139) | def _use_pixels(self):
method seed (line 144) | def seed(self) -> Optional[int]:
method success (line 149) | def success(self) -> bool:
method fail (line 154) | def fail(self) -> bool:
method reward (line 159) | def reward(self) -> float:
method terminate (line 164) | def terminate(self) -> bool:
method truncate (line 169) | def truncate(self) -> bool:
method is_healthy (line 174) | def is_healthy(self) -> bool:
method observation_config (line 179) | def observation_config(self) -> ObservationConfig:
method control_frequency (line 184) | def control_frequency(self):
method robot (line 189) | def robot(self) -> Robot:
method floor (line 194) | def floor(self) -> Geom:
method mojo (line 199) | def mojo(self) -> Mojo:
method action (line 204) | def action(self) -> np.ndarray:
method _initialize_renderers (line 208) | def _initialize_renderers(self):
method _initialize_cameras (line 219) | def _initialize_cameras(self) -> dict[str, tuple[int, Camera]]:
method _close_renderers (line 240) | def _close_renderers(self):
method _initialize_env (line 248) | def _initialize_env(self):
method get_observation_space (line 252) | def get_observation_space(self) -> spaces.Space:
method _get_task_privileged_obs_space (line 307) | def _get_task_privileged_obs_space(self) -> dict[str, Any]:
method get_observation (line 311) | def get_observation(self) -> dict[str, np.ndarray]:
method _get_task_info (line 322) | def _get_task_info(self) -> dict[str, Any]:
method get_info (line 326) | def get_info(self) -> dict[str, Any]:
method _get_proprioception_obs (line 332) | def _get_proprioception_obs(self) -> dict[str, Any]:
method _get_visual_obs (line 350) | def _get_visual_obs(self) -> dict[str, Any]:
method _get_task_privileged_obs (line 367) | def _get_task_privileged_obs(self) -> dict[str, Any]:
method _update_seed (line 371) | def _update_seed(self, override_seed=None):
method reset (line 392) | def reset(self, *, seed: Optional[int] = None, options: Optional[dict]...
method _on_reset (line 408) | def _on_reset(self):
method _on_step (line 412) | def _on_step(self):
method render (line 416) | def render(self):
method step (line 420) | def step(
method _step_mujoco_simulation (line 449) | def _step_mujoco_simulation(self, action):
method _success (line 474) | def _success(self) -> bool:
method _fail (line 478) | def _fail(self) -> bool:
method _reward (line 484) | def _reward(self) -> float:
method close (line 488) | def close(self):
FILE: bigym/bigym_renderer.py
class BiGymRenderer (line 15) | class BiGymRenderer(MujocoRenderer):
method __init__ (line 22) | def __init__(self, mojo: Mojo):
method _get_viewer (line 26) | def _get_viewer(self, render_mode: str) -> BaseRender:
method get_viewer (line 47) | def get_viewer(self, render_mode: str) -> BaseRender:
class BiGymWindowViewer (line 52) | class BiGymWindowViewer(WindowViewer):
method render (line 59) | def render(self):
FILE: bigym/const.py
class ActuatorGroup (line 20) | class ActuatorGroup(IntEnum):
class HandSide (line 28) | class HandSide(Enum):
FILE: bigym/envs/cupboards.py
class _CupboardsInteractionEnv (line 14) | class _CupboardsInteractionEnv(BiGymEnv, ABC):
method _initialize_env (line 21) | def _initialize_env(self):
class DrawerTopOpen (line 34) | class DrawerTopOpen(_CupboardsInteractionEnv):
method _success (line 37) | def _success(self) -> bool:
class DrawerTopClose (line 41) | class DrawerTopClose(_CupboardsInteractionEnv):
method _success (line 44) | def _success(self) -> bool:
method _on_reset (line 47) | def _on_reset(self):
class DrawersAllOpen (line 51) | class DrawersAllOpen(_CupboardsInteractionEnv):
method _success (line 54) | def _success(self) -> bool:
class DrawersAllClose (line 58) | class DrawersAllClose(_CupboardsInteractionEnv):
method _success (line 61) | def _success(self) -> bool:
method _on_reset (line 64) | def _on_reset(self):
class WallCupboardOpen (line 68) | class WallCupboardOpen(_CupboardsInteractionEnv):
method _success (line 71) | def _success(self) -> bool:
class WallCupboardClose (line 75) | class WallCupboardClose(_CupboardsInteractionEnv):
method _success (line 78) | def _success(self) -> bool:
method _on_reset (line 81) | def _on_reset(self):
class CupboardsOpenAll (line 85) | class CupboardsOpenAll(_CupboardsInteractionEnv):
method _success (line 88) | def _success(self) -> bool:
class CupboardsCloseAll (line 95) | class CupboardsCloseAll(_CupboardsInteractionEnv):
method _success (line 98) | def _success(self) -> bool:
method _on_reset (line 104) | def _on_reset(self):
FILE: bigym/envs/dishwasher.py
class _DishwasherEnv (line 11) | class _DishwasherEnv(BiGymEnv, ABC):
method _initialize_env (line 19) | def _initialize_env(self):
class DishwasherOpen (line 23) | class DishwasherOpen(_DishwasherEnv):
method _success (line 26) | def _success(self) -> bool:
method _on_reset (line 29) | def _on_reset(self):
class DishwasherClose (line 33) | class DishwasherClose(_DishwasherEnv):
method _success (line 36) | def _success(self) -> bool:
method _on_reset (line 39) | def _on_reset(self):
class DishwasherCloseTrays (line 43) | class DishwasherCloseTrays(DishwasherClose):
method _success (line 46) | def _success(self) -> bool:
class DishwasherOpenTrays (line 50) | class DishwasherOpenTrays(DishwasherClose):
method _success (line 53) | def _success(self) -> bool:
method _on_reset (line 56) | def _on_reset(self):
FILE: bigym/envs/dishwasher_cups.py
class _DishwasherCupsEnv (line 15) | class _DishwasherCupsEnv(BiGymEnv, ABC):
method _initialize_env (line 23) | def _initialize_env(self):
method _fail (line 28) | def _fail(self) -> bool:
method _on_reset (line 36) | def _on_reset(self):
class DishwasherUnloadCups (line 40) | class DishwasherUnloadCups(_DishwasherCupsEnv):
method _success (line 52) | def _success(self) -> bool:
method _on_reset (line 61) | def _on_reset(self):
class DishwasherUnloadCupsLong (line 77) | class DishwasherUnloadCupsLong(DishwasherUnloadCups):
method _initialize_env (line 85) | def _initialize_env(self):
method _success (line 89) | def _success(self) -> bool:
class DishwasherLoadCups (line 103) | class DishwasherLoadCups(_DishwasherCupsEnv):
method _success (line 113) | def _success(self) -> bool:
method _on_reset (line 122) | def _on_reset(self):
FILE: bigym/envs/dishwasher_cutlery.py
class _DishwasherCutleryEnv (line 18) | class _DishwasherCutleryEnv(BiGymEnv, ABC):
method _initialize_env (line 28) | def _initialize_env(self):
method _fail (line 32) | def _fail(self) -> bool:
method _on_reset (line 40) | def _on_reset(self):
class _DishwasherUnloadCutleryEnv (line 44) | class _DishwasherUnloadCutleryEnv(_DishwasherCutleryEnv):
method _on_reset (line 53) | def _on_reset(self):
class DishwasherUnloadCutlery (line 69) | class DishwasherUnloadCutlery(_DishwasherUnloadCutleryEnv):
method _initialize_env (line 76) | def _initialize_env(self):
method _success (line 80) | def _success(self) -> bool:
method _on_reset (line 89) | def _on_reset(self):
class DishwasherUnloadCutleryLong (line 96) | class DishwasherUnloadCutleryLong(_DishwasherUnloadCutleryEnv):
method _initialize_env (line 103) | def _initialize_env(self):
method _success (line 108) | def _success(self) -> bool:
class DishwasherLoadCutlery (line 122) | class DishwasherLoadCutlery(_DishwasherCutleryEnv):
method _initialize_env (line 135) | def _initialize_env(self):
method _success (line 139) | def _success(self) -> bool:
method _on_reset (line 148) | def _on_reset(self):
FILE: bigym/envs/dishwasher_plates.py
class _DishwasherPlatesEnv (line 17) | class _DishwasherPlatesEnv(BiGymEnv, ABC):
method _initialize_env (line 36) | def _initialize_env(self):
method _fail (line 43) | def _fail(self) -> bool:
method _on_reset (line 51) | def _on_reset(self):
class DishwasherUnloadPlates (line 57) | class DishwasherUnloadPlates(_DishwasherPlatesEnv):
method _success (line 60) | def _success(self) -> bool:
method _on_reset (line 69) | def _on_reset(self):
class DishwasherUnloadPlatesLong (line 80) | class DishwasherUnloadPlatesLong(DishwasherUnloadPlates):
method _initialize_env (line 91) | def _initialize_env(self):
method _success (line 95) | def _success(self) -> bool:
class DishwasherLoadPlates (line 103) | class DishwasherLoadPlates(_DishwasherPlatesEnv):
method _success (line 106) | def _success(self) -> bool:
method _on_reset (line 124) | def _on_reset(self):
FILE: bigym/envs/groceries.py
class GroceriesStoreLower (line 14) | class GroceriesStoreLower(BiGymEnv):
method _initialize_env (line 30) | def _initialize_env(self):
method _on_reset (line 40) | def _on_reset(self):
method _success (line 61) | def _success(self) -> bool:
class GroceriesStoreUpper (line 75) | class GroceriesStoreUpper(GroceriesStoreLower):
method _initialize_env (line 80) | def _initialize_env(self):
method _success (line 85) | def _success(self) -> bool:
FILE: bigym/envs/manipulation.py
class _ManipulationEnv (line 19) | class _ManipulationEnv(BiGymEnv, ABC):
method _initialize_env (line 24) | def _initialize_env(self):
class FlipCup (line 28) | class FlipCup(_ManipulationEnv):
method _initialize_env (line 41) | def _initialize_env(self):
method _success (line 45) | def _success(self) -> bool:
method _on_reset (line 58) | def _on_reset(self):
class FlipCutlery (line 73) | class FlipCutlery(_ManipulationEnv):
method _initialize_env (line 90) | def _initialize_env(self):
method _success (line 95) | def _success(self) -> bool:
method _on_reset (line 109) | def _on_reset(self):
class StackBlocks (line 126) | class StackBlocks(BiGymEnv):
method _initialize_env (line 143) | def _initialize_env(self):
method _on_reset (line 154) | def _on_reset(self):
method _success (line 170) | def _success(self) -> bool:
method _fail (line 184) | def _fail(self) -> bool:
FILE: bigym/envs/move_plates.py
class _MovePlatesEnv (line 24) | class _MovePlatesEnv(BiGymEnv, ABC):
method _initialize_env (line 34) | def _initialize_env(self):
method _success (line 40) | def _success(self) -> bool:
method _fail (line 64) | def _fail(self) -> bool:
method _on_reset (line 72) | def _on_reset(self):
class MovePlate (line 88) | class MovePlate(_MovePlatesEnv):
method _get_task_privileged_obs_space (line 91) | def _get_task_privileged_obs_space(self):
method _get_task_privileged_obs (line 101) | def _get_task_privileged_obs(self):
class MoveTwoPlates (line 108) | class MoveTwoPlates(_MovePlatesEnv):
method _get_task_privileged_obs_space (line 113) | def _get_task_privileged_obs_space(self):
method _get_task_privileged_obs (line 116) | def _get_task_privileged_obs(self):
FILE: bigym/envs/pick_and_place.py
class PutCups (line 17) | class PutCups(BiGymEnv):
method _initialize_env (line 31) | def _initialize_env(self):
method _success (line 36) | def _success(self) -> bool:
method _on_reset (line 45) | def _on_reset(self):
class TakeCups (line 61) | class TakeCups(PutCups):
method _success (line 66) | def _success(self) -> bool:
class StoreBox (line 76) | class StoreBox(BiGymEnv):
method _initialize_env (line 85) | def _initialize_env(self):
method _on_reset (line 89) | def _on_reset(self):
method _success (line 95) | def _success(self) -> bool:
class PickBox (line 104) | class PickBox(StoreBox):
method _success (line 110) | def _success(self) -> bool:
method _on_reset (line 118) | def _on_reset(self):
class SaucepanToHob (line 127) | class SaucepanToHob(BiGymEnv):
method _initialize_env (line 137) | def _initialize_env(self):
method _success (line 141) | def _success(self) -> bool:
method _on_reset (line 149) | def _on_reset(self):
class StoreKitchenware (line 158) | class StoreKitchenware(BiGymEnv):
method _initialize_env (line 168) | def _initialize_env(self):
method _success (line 172) | def _success(self) -> bool:
method _on_reset (line 181) | def _on_reset(self):
class ToastSandwich (line 193) | class ToastSandwich(BiGymEnv):
method _sandwich_anchor (line 219) | def _sandwich_anchor(self) -> Prop:
method _initialize_env (line 222) | def _initialize_env(self):
method _on_reset (line 231) | def _on_reset(self):
method _success (line 250) | def _success(self) -> bool:
method _fail (line 263) | def _fail(self) -> bool:
class FlipSandwich (line 272) | class FlipSandwich(ToastSandwich):
method _sandwich_anchor (line 282) | def _sandwich_anchor(self) -> Prop:
method _success (line 285) | def _success(self) -> bool:
class RemoveSandwich (line 298) | class RemoveSandwich(FlipSandwich):
method _success (line 303) | def _success(self) -> bool:
FILE: bigym/envs/props/cabintets.py
class ModularCabinet (line 15) | class ModularCabinet(CollidableProp, ABC):
method _post_init (line 18) | def _post_init(self):
method set_state (line 21) | def set_state(self, state: np.ndarray):
method get_state (line 26) | def get_state(self) -> np.ndarray[float]:
method _toggle_body (line 31) | def _toggle_body(model: mjcf.RootElement, name: str, enable: bool):
class BaseCabinet (line 36) | class BaseCabinet(ModularCabinet):
method _model_path (line 56) | def _model_path(self) -> Path:
method _parse_kwargs (line 59) | def _parse_kwargs(self, kwargs: dict[str, Any]):
method _on_loaded (line 83) | def _on_loaded(self, model: mjcf.RootElement):
class WallCabinet (line 102) | class WallCabinet(ModularCabinet):
method _model_path (line 112) | def _model_path(self) -> Path:
method _parse_kwargs (line 115) | def _parse_kwargs(self, kwargs: dict[str, Any]):
method _on_loaded (line 120) | def _on_loaded(self, model: mjcf.RootElement):
class OpenShelf (line 132) | class OpenShelf(ModularCabinet):
method _model_path (line 138) | def _model_path(self) -> Path:
method _on_loaded (line 141) | def _on_loaded(self, model: mjcf.RootElement):
FILE: bigym/envs/props/cutlery.py
class Fork (line 9) | class Fork(KinematicProp):
method _model_path (line 13) | def _model_path(self) -> Path:
class Knife (line 17) | class Knife(KinematicProp):
method _model_path (line 21) | def _model_path(self) -> Path:
class Spoon (line 25) | class Spoon(KinematicProp):
method _model_path (line 29) | def _model_path(self) -> Path:
class Spatula (line 33) | class Spatula(KinematicProp):
method _model_path (line 37) | def _model_path(self) -> Path:
FILE: bigym/envs/props/dishwasher.py
class DishwasherPart (line 14) | class DishwasherPart:
method __init__ (line 17) | def __init__(
class Dishwasher (line 46) | class Dishwasher(Prop):
method _model_path (line 70) | def _model_path(self) -> Path:
method _post_init (line 73) | def _post_init(self):
method set_state (line 96) | def set_state(self, door: float, bottom_tray: float, middle_tray: float):
method get_state (line 102) | def get_state(self) -> np.ndarray:
FILE: bigym/envs/props/holders.py
class _Holder (line 11) | class _Holder(Prop, ABC):
class CutleryTray (line 18) | class CutleryTray(_Holder):
method _model_path (line 22) | def _model_path(self) -> Path:
class DishDrainer (line 26) | class DishDrainer(_Holder):
method _model_path (line 30) | def _model_path(self) -> Path:
method _post_init (line 33) | def _post_init(self):
FILE: bigym/envs/props/items.py
class Box (line 12) | class Box(KinematicProp):
method _model_path (line 16) | def _model_path(self) -> Path:
class Cube (line 20) | class Cube(KinematicProp):
method _model_path (line 24) | def _model_path(self) -> Path:
class Sandwich (line 28) | class Sandwich(KinematicProp):
method _model_path (line 38) | def _model_path(self) -> Path:
method _parse_kwargs (line 42) | def _parse_kwargs(self, kwargs: dict[str, Any]):
method _on_loaded (line 46) | def _on_loaded(self, model: mjcf.RootElement):
class Wine (line 53) | class Wine(KinematicProp):
method _model_path (line 57) | def _model_path(self) -> Path:
class Detergent (line 61) | class Detergent(KinematicProp):
method _model_path (line 65) | def _model_path(self) -> Path:
class Soap (line 69) | class Soap(KinematicProp):
method _model_path (line 73) | def _model_path(self) -> Path:
class Beer (line 77) | class Beer(KinematicProp):
method _model_path (line 81) | def _model_path(self) -> Path:
class Cereals (line 85) | class Cereals(KinematicProp):
method _model_path (line 89) | def _model_path(self) -> Path:
class Crisps (line 93) | class Crisps(KinematicProp):
method _model_path (line 97) | def _model_path(self) -> Path:
class Ketchup (line 101) | class Ketchup(KinematicProp):
method _model_path (line 105) | def _model_path(self) -> Path:
class Mustard (line 109) | class Mustard(KinematicProp):
method _model_path (line 113) | def _model_path(self) -> Path:
class Soda (line 117) | class Soda(KinematicProp):
method _model_path (line 121) | def _model_path(self) -> Path:
FILE: bigym/envs/props/kitchenware.py
class Plate (line 8) | class Plate(KinematicProp):
method _model_path (line 12) | def _model_path(self) -> Path:
class Mug (line 16) | class Mug(KinematicProp):
method _model_path (line 20) | def _model_path(self) -> Path:
class Pan (line 24) | class Pan(KinematicProp):
method _model_path (line 28) | def _model_path(self) -> Path:
class Saucepan (line 32) | class Saucepan(KinematicProp):
method _model_path (line 36) | def _model_path(self) -> Path:
class ChoppingBoard (line 40) | class ChoppingBoard(KinematicProp):
method _model_path (line 44) | def _model_path(self) -> Path:
FILE: bigym/envs/props/preset.py
class Preset (line 17) | class Preset:
method __init__ (line 20) | def __init__(self, mojo: Mojo, path: Optional[Path]):
method get_props (line 39) | def get_props(self, prop_type: Optional[Type[PT]] = None) -> list[PT]:
method _load_prop (line 46) | def _load_prop(
method _get_float_array (line 84) | def _get_float_array(
FILE: bigym/envs/props/prop.py
class Prop (line 15) | class Prop(ABC):
method __init__ (line 24) | def __init__(
method _model_path (line 70) | def _model_path(self) -> Path:
method _parse_kwargs (line 73) | def _parse_kwargs(self, kwargs: dict[str, Any]):
method _on_loaded (line 77) | def _on_loaded(self, model: mjcf.RootElement):
method _post_init (line 81) | def _post_init(self):
method get_pose (line 85) | def get_pose(self) -> np.ndarray:
method set_pose (line 92) | def set_pose(
method disable (line 114) | def disable(self):
method enable (line 125) | def enable(self):
method get_velocities (line 136) | def get_velocities(self) -> np.ndarray:
method is_static (line 143) | def is_static(self, atol_pos: float = 1.0e-3):
method is_colliding (line 148) | def is_colliding(self, other: Union[Geom, Iterable[Geom], "Prop"]) -> ...
method get_body_colliders (line 156) | def get_body_colliders(body: Body) -> list[Geom]:
method get_body_sites (line 161) | def get_body_sites(body: Body, mojo: Mojo) -> list[Site]:
class CollidableProp (line 167) | class CollidableProp(Prop, ABC):
class KinematicProp (line 173) | class KinematicProp(Prop, ABC):
FILE: bigym/envs/props/tables.py
class Table (line 9) | class Table(CollidableProp):
method _model_path (line 13) | def _model_path(self) -> Path:
class SmallTable (line 17) | class SmallTable(CollidableProp):
method _model_path (line 21) | def _model_path(self) -> Path:
FILE: bigym/envs/reach_target.py
class TargetConfig (line 17) | class TargetConfig:
class Target (line 27) | class Target:
method __init__ (line 30) | def __init__(self, mojo: Mojo, robot: Robot, config: TargetConfig):
method reset_position (line 45) | def reset_position(self, offset: np.ndarray = np.zeros(3)):
method distance (line 49) | def distance(self, pos: np.ndarray) -> float:
method is_reached (line 53) | def is_reached(self, tolerance: float) -> bool:
method set_highlight (line 65) | def set_highlight(self, highlight: bool):
class _ReachTargetEnv (line 72) | class _ReachTargetEnv(BiGymEnv, ABC):
method _initialize_env (line 87) | def _initialize_env(self):
method _on_reset (line 92) | def _on_reset(self):
method _success (line 98) | def _success(self) -> bool:
method _on_step (line 104) | def _on_step(self):
class ReachTarget (line 109) | class ReachTarget(_ReachTargetEnv):
method _get_task_privileged_obs_space (line 112) | def _get_task_privileged_obs_space(self):
method _get_task_privileged_obs (line 119) | def _get_task_privileged_obs(self):
class ReachTargetSingle (line 127) | class ReachTargetSingle(ReachTarget):
class ReachTargetDual (line 140) | class ReachTargetDual(_ReachTargetEnv):
method _get_task_privileged_obs_space (line 158) | def _get_task_privileged_obs_space(self):
method _get_task_privileged_obs (line 168) | def _get_task_privileged_obs(self):
FILE: bigym/robots/animated_legs.py
class AnimatedLegs (line 15) | class AnimatedLegs(ABC):
method __init__ (line 18) | def __init__(self, mojo: Mojo, pelvis: Body):
method step (line 24) | def step(self, pelvis_z: float, is_moving: bool = True):
class H1AnimatedLegs (line 29) | class H1AnimatedLegs(AnimatedLegs):
method __init__ (line 64) | def __init__(self, mojo: Mojo, pelvis: Body):
method step (line 78) | def step(self, pelvis_z: float, is_moving: bool = True):
method _on_loaded (line 92) | def _on_loaded(self, model: mjcf.RootElement):
method _get_offset (line 109) | def _get_offset(self, shift: float, scale: float) -> float:
method _set_leg_state (line 118) | def _set_leg_state(self, leg: list[Body], state: np.ndarray):
method _solve (line 124) | def _solve(self, pelvis_z: float, offset: float = 0.0) -> np.ndarray:
FILE: bigym/robots/config.py
class GripperConfig (line 17) | class GripperConfig:
method __post_init__ (line 37) | def __post_init__(self):
class ArmConfig (line 44) | class ArmConfig:
class FloatingBaseConfig (line 63) | class FloatingBaseConfig:
class FullBodyConfig (line 75) | class FullBodyConfig:
class RobotConfig (line 83) | class RobotConfig:
FILE: bigym/robots/configs/google_robot.py
class GoogleRobot (line 86) | class GoogleRobot(Robot):
method config (line 90) | def config(self) -> RobotConfig:
FILE: bigym/robots/configs/h1.py
class H1 (line 173) | class H1(Robot):
method config (line 177) | def config(self) -> RobotConfig:
class H1FineManipulation (line 182) | class H1FineManipulation(Robot):
method config (line 186) | def config(self) -> RobotConfig:
FILE: bigym/robots/configs/stretch.py
class StretchRobot (line 86) | class StretchRobot(Robot):
method config (line 90) | def config(self) -> RobotConfig:
FILE: bigym/robots/floating_base.py
class RobotFloatingBase (line 21) | class RobotFloatingBase:
method __init__ (line 27) | def __init__(
method reset (line 90) | def reset(self, position: np.ndarray, quaternion: np.ndarray):
method get_action_bounds (line 100) | def get_action_bounds(self) -> list[tuple[float, float]]:
method set_control (line 111) | def set_control(self, control: np.ndarray):
method is_target_reached (line 138) | def is_target_reached(self) -> bool:
method dof_amount (line 153) | def dof_amount(self) -> int:
method qpos (line 158) | def qpos(self) -> np.ndarray:
method qvel (line 170) | def qvel(self) -> np.ndarray:
method get_accumulated_actions (line 182) | def get_accumulated_actions(self) -> np.ndarray:
method all_actuators (line 187) | def all_actuators(self) -> list[mjcf.Element]:
method position_actuators (line 194) | def position_actuators(self) -> list[Optional[mjcf.Element]]:
method rotation_actuators (line 199) | def rotation_actuators(self) -> list[Optional[mjcf.Element]]:
method _pelvis_z (line 204) | def _pelvis_z(self) -> float:
method _set_position (line 212) | def _set_position(self, position: np.ndarray):
method _set_quaternion (line 216) | def _set_quaternion(self, quaternion: np.ndarray):
method _set_value (line 220) | def _set_value(self, position: bool, values: np.ndarray):
method _add_actuator (line 238) | def _add_actuator(self, positional: bool, axis: np.ndarray, actuator: ...
FILE: bigym/robots/gripper.py
class Gripper (line 16) | class Gripper:
method __init__ (line 22) | def __init__(
method body (line 57) | def body(self) -> Body:
method wrist_site (line 62) | def wrist_site(self) -> Site:
method pinch_position (line 67) | def pinch_position(self) -> np.ndarray:
method wrist_position (line 72) | def wrist_position(self) -> np.ndarray:
method range (line 77) | def range(self) -> np.ndarray:
method actuators (line 82) | def actuators(self) -> list[mjcf.Element]:
method qpos (line 87) | def qpos(self) -> float:
method qvel (line 98) | def qvel(self) -> float:
method is_holding_object (line 106) | def is_holding_object(self, other: Union[Geom, Iterable[Geom], Prop]) ...
method set_control (line 112) | def set_control(self, ctrl: float):
method _on_loaded (line 123) | def _on_loaded(self, model: mjcf.RootElement):
method _process_gripper (line 127) | def _process_gripper(
method _get_pad_geoms (line 159) | def _get_pad_geoms(self) -> list[Geom]:
FILE: bigym/robots/robot.py
class ActuatorType (line 33) | class ActuatorType(Enum):
class Robot (line 41) | class Robot(ABC):
method __init__ (line 44) | def __init__(
method config (line 66) | def config(self) -> RobotConfig:
method action_mode (line 71) | def action_mode(self) -> ActionMode:
method pelvis (line 76) | def pelvis(self) -> Body:
method limb_actuators (line 81) | def limb_actuators(self) -> list[mjcf.Element]:
method grippers (line 86) | def grippers(self) -> dict[HandSide, Gripper]:
method floating_base (line 91) | def floating_base(self) -> Optional[RobotFloatingBase]:
method cameras (line 96) | def cameras(self) -> list[Camera]:
method qpos (line 101) | def qpos(self) -> np.ndarray:
method qpos_grippers (line 108) | def qpos_grippers(self) -> np.ndarray:
method qpos_actuated (line 116) | def qpos_actuated(self) -> np.ndarray:
method qvel (line 127) | def qvel(self) -> np.ndarray:
method qvel_actuated (line 134) | def qvel_actuated(self) -> np.ndarray:
method get_hand_pos (line 145) | def get_hand_pos(self, side: HandSide) -> np.ndarray:
method is_gripper_holding_object (line 151) | def is_gripper_holding_object(
method reset (line 159) | def reset(self, position: np.ndarray, orientation: np.ndarray):
method _set_pose (line 170) | def _set_pose(self, position: np.ndarray, orientation: np.ndarray):
method get_limb_control_range (line 178) | def get_limb_control_range(
method _get_grippers (line 187) | def _get_grippers(self) -> dict[HandSide, Gripper]:
method _get_joints (line 199) | def _get_joints(self) -> list[Joint]:
method _on_loaded (line 204) | def _on_loaded(self, model: mjcf.RootElement):
method _add_wrist (line 317) | def _add_wrist(model: mjcf.RootElement, side: HandSide, arm_config: Ar...
FILE: bigym/utils/callables_cache.py
class CallablesCache (line 7) | class CallablesCache:
method __init__ (line 10) | def __init__(self):
method get (line 15) | def get(self, func: Callable) -> Any:
method clean (line 26) | def clean(self):
FILE: bigym/utils/dof.py
class Dof (line 9) | class Dof:
FILE: bigym/utils/env_health.py
class UnstableSimulationWarning (line 9) | class UnstableSimulationWarning(UserWarning):
class UnstableSimulationError (line 13) | class UnstableSimulationError(RuntimeError):
class EnvHealth (line 17) | class EnvHealth:
method __init__ (line 26) | def __init__(self):
method reset (line 31) | def reset(self):
method track (line 38) | def track(self):
method is_healthy (line 55) | def is_healthy(self) -> bool:
FILE: bigym/utils/env_utils.py
function get_random_sites (line 7) | def get_random_sites(
function get_random_points_on_plane (line 38) | def get_random_points_on_plane(
FILE: bigym/utils/observation_config.py
class CameraConfig (line 7) | class CameraConfig:
method __post_init__ (line 17) | def __post_init__(self):
method from_safetensors_metadata (line 32) | def from_safetensors_metadata(cls, metadata: dict):
method to_string (line 38) | def to_string(self):
class ObservationConfig (line 50) | class ObservationConfig:
method from_safetensors_metadata (line 58) | def from_safetensors_metadata(cls, metadata: dict):
FILE: bigym/utils/physics_utils.py
function get_critical_damping_from_stiffness (line 13) | def get_critical_damping_from_stiffness(
function is_target_reached (line 31) | def is_target_reached(actuator: mjcf.Element, physics: mjcf.Physics, tol...
function distance (line 40) | def distance(element1: MujocoElement, element2: MujocoElement):
function set_joint_position (line 46) | def set_joint_position(joint: Joint, value: float, normalized: bool = Fa...
function get_joint_position (line 58) | def get_joint_position(joint: Joint, normalized: bool = False) -> float:
function get_actuator_qpos (line 67) | def get_actuator_qpos(actuator: mjcf.Element, physics: mjcf.Physics) -> ...
function get_actuator_qvel (line 77) | def get_actuator_qvel(actuator: mjcf.Element, physics: mjcf.Physics) -> ...
function get_colliders (line 91) | def get_colliders(obj: Union[Geom, Iterable[Geom], Any]) -> Iterable[Geom]:
function has_collided_collections (line 108) | def has_collided_collections(
FILE: bigym/utils/robot_highlighter.py
class RobotHighlighter (line 12) | class RobotHighlighter:
method __init__ (line 15) | def __init__(self, robot: Robot, mojo: Mojo):
method reset (line 39) | def reset(self):
method highlight (line 45) | def highlight(self, index: int, tint: np.ndarray = np.array([1, 1, 1, ...
FILE: bigym/utils/shared.py
function find_class_in_module (line 11) | def find_class_in_module(module: ModuleType, class_name: str) -> Optiona...
function find_constant_in_module (line 16) | def find_constant_in_module(module: ModuleType, constant_name: str) -> O...
function _find_member_in_module (line 21) | def _find_member_in_module(
FILE: demonstrations/demo.py
class DemoStep (line 40) | class DemoStep:
method __init__ (line 49) | def __init__(self, observation, reward, termination, truncation, info,...
method executed_action (line 68) | def executed_action(self) -> ActType:
method set_executed_action (line 72) | def set_executed_action(self, action):
method has_visual_observations (line 78) | def has_visual_observations(self) -> bool:
method visual_observations (line 86) | def visual_observations(self) -> dict[str, np.ndarray]:
class Demo (line 95) | class Demo:
method __init__ (line 98) | def __init__(
method from_safetensors (line 116) | def from_safetensors(
method from_env (line 146) | def from_env(cls, env: BiGymEnv) -> Demo:
method load_timesteps_from_safetensors (line 160) | def load_timesteps_from_safetensors(
method _saving_format (line 226) | def _saving_format(self):
method save (line 249) | def save(self, path: Union[str, Path]) -> Path:
method timesteps (line 290) | def timesteps(self) -> list[DemoStep]:
method duration (line 295) | def duration(self) -> int:
method seed (line 300) | def seed(self):
method metadata (line 305) | def metadata(self) -> Metadata:
method uuid (line 310) | def uuid(self):
method safetensor_metadata (line 315) | def safetensor_metadata(self):
method add_timestep (line 319) | def add_timestep(self, observation, reward, termination, truncation, i...
method add_termination_steps (line 333) | def add_termination_steps(self, steps_count: int):
class LightweightDemo (line 339) | class LightweightDemo(Demo):
method __init__ (line 342) | def __init__(
method from_safetensors (line 361) | def from_safetensors(
method from_demo (line 394) | def from_demo(cls, demo: Demo) -> LightweightDemo:
method from_env (line 409) | def from_env(cls, env: BiGymEnv) -> Demo:
method _saving_format (line 423) | def _saving_format(self):
method add_timestep (line 442) | def add_timestep(self, observation, reward, termination, truncation, i...
method lighten_timesteps (line 457) | def lighten_timesteps(timesteps: list[DemoStep]) -> list[DemoStep]:
FILE: demonstrations/demo_converter.py
class DemoConverter (line 17) | class DemoConverter:
method absolute_to_delta (line 21) | def absolute_to_delta(demo: Demo) -> Demo:
method clip_actions (line 70) | def clip_actions(demo: Demo, action_scale: float = 1) -> Demo:
method decimate (line 83) | def decimate(
method create_demo_in_new_env (line 140) | def create_demo_in_new_env(
FILE: demonstrations/demo_player.py
class DemoPlayer (line 11) | class DemoPlayer:
method replay (line 15) | def replay(
method replay_in_env (line 26) | def replay_in_env(
method validate (line 40) | def validate(
method validate_in_env (line 50) | def validate_in_env(
method _get_timesteps_for_replay (line 67) | def _get_timesteps_for_replay(
FILE: demonstrations/demo_recorder.py
class DemoRecorder (line 10) | class DemoRecorder:
method __init__ (line 13) | def __init__(self, demo_dir: Optional[Union[str, Path]] = None):
method __del__ (line 30) | def __del__(self):
method record (line 35) | def record(self, env: BiGymEnv, lightweight_demo: bool = False):
method stop (line 51) | def stop(self):
method add_timestep (line 56) | def add_timestep(self, timestep: tuple, action):
method timesteps (line 67) | def timesteps(self) -> list[DemoStep]:
method demo (line 72) | def demo(self) -> Optional[Demo]:
method save_demo (line 76) | def save_demo(self, filename: Optional[str] = None) -> Optional[Path]:
method is_recording (line 97) | def is_recording(self):
FILE: demonstrations/demo_store.py
class DemoNotFoundError (line 24) | class DemoNotFoundError(Exception):
method __init__ (line 27) | def __init__(self, metadata: Metadata):
class TooManyDemosRequestedError (line 37) | class TooManyDemosRequestedError(Exception):
method __init__ (line 40) | def __init__(self, requested: int, found: int):
class DemoStore (line 55) | class DemoStore:
method __init__ (line 61) | def __init__(self, cache_root: Optional[Path] = None):
method cache_demo (line 67) | def cache_demo(self, demo: Demo, frequency: Optional[int] = None):
method _cache_demo_file (line 84) | def _cache_demo_file(self, demo_path: Path, frequency: Optional[int] =...
method get_demos (line 90) | def get_demos(
method _get_demos (line 161) | def _get_demos(self, demos_dir: Path, amount: int) -> list[Demo]:
method _get_demos_count (line 173) | def _get_demos_count(self, demos_dir: Path) -> int:
method pull_demos (line 179) | def pull_demos(self):
method cached (line 200) | def cached(self):
method cached (line 206) | def cached(self, value: bool):
method list_demo_paths (line 214) | def list_demo_paths(self, metadata: Metadata) -> list[Path]:
method _create_path (line 222) | def _create_path(self, metadata: Metadata, frequency: Optional[int] = ...
method light_demo_exists (line 238) | def light_demo_exists(
method demo_exists (line 256) | def demo_exists(
FILE: demonstrations/utils.py
class ObservationMode (line 37) | class ObservationMode(Enum):
class Metadata (line 46) | class Metadata:
method from_safetensors (line 61) | def from_safetensors(cls, demo_path: Path):
method from_env (line 75) | def from_env(cls, env: BiGymEnv, is_lightweight: bool = False):
method from_env_cls (line 94) | def from_env_cls(
method ready_for_safetensors (line 125) | def ready_for_safetensors(self) -> dict:
method env_name (line 137) | def env_name(self) -> str:
method filename (line 142) | def filename(self) -> str:
method floating_dof_count (line 147) | def floating_dof_count(self) -> int:
method env_cls (line 154) | def env_cls(self) -> Type[BiGymEnv]:
method robot_cls (line 159) | def robot_cls(self) -> Type[Robot]:
method action_mode_cls (line 164) | def action_mode_cls(self) -> Type[ActionMode]:
method _check_package_versions (line 168) | def _check_package_versions(self):
method get_env (line 179) | def get_env(
method get_action_mode (line 191) | def get_action_mode(self) -> ActionMode:
method get_action_space (line 216) | def get_action_space(self, action_scale: float) -> spaces.Box:
method get_robot (line 222) | def get_robot(self) -> Robot:
class EnvData (line 228) | class EnvData:
method __post_init__ (line 240) | def __post_init__(self):
method from_safetensors_metadata (line 250) | def from_safetensors_metadata(cls, metadata: dict):
method from_env (line 258) | def from_env(cls, env: BiGymEnv):
method action_mode_description (line 284) | def action_mode_description(self) -> str:
method camera_description (line 296) | def camera_description(self) -> str:
method env_cls (line 305) | def env_cls(self) -> Type[BiGymEnv]:
method action_mode_cls (line 315) | def action_mode_cls(self) -> Type[ActionMode]:
method robot_cls (line 327) | def robot_cls(self) -> Type[Robot]:
function get_package_version (line 337) | def get_package_version(package_name: str) -> Optional[str]:
function decode_safetensors_metadata (line 345) | def decode_safetensors_metadata(metadata: dict) -> dict:
function clean_metadata (line 365) | def clean_metadata(metadata: dict, cls: Type[dataclass]) -> dict:
FILE: doc/scripts/download_and_validate_demos.py
function validate_all_demos (line 34) | def validate_all_demos(env_cls: Type[BiGymEnv]):
FILE: doc/scripts/preview_renderer.py
class Resolution (line 20) | class Resolution(enum.Enum):
class PreviewRenderer (line 29) | class PreviewRenderer:
method render (line 30) | def render(
method render_demo (line 70) | def render_demo(
method _env_name (line 109) | def _env_name(env_cls: Type[BiGymEnv]) -> str:
method _get_output_dir (line 113) | def _get_output_dir() -> Path:
FILE: doc/scripts/render_demos.py
function get_camera (line 19) | def get_camera() -> mujoco.MjvCamera:
FILE: examples/record_and_replay_demo.py
function update_plots (line 22) | def update_plots(axs, requested, expected, actual, xlim=None, ylim=None):
function init_subplots (line 39) | def init_subplots(n):
FILE: setup.py
function read (line 8) | def read(rel_path):
function get_version (line 14) | def get_version(rel_path):
FILE: tests/conftest.py
function pytest_addoption (line 4) | def pytest_addoption(parser):
function pytest_collection_modifyitems (line 10) | def pytest_collection_modifyitems(config, items):
FILE: tests/tasks/test_move_plate.py
class TestMovePlate (line 14) | class TestMovePlate:
method test_terminates_when_plate_is_on_the_ground (line 15) | def test_terminates_when_plate_is_on_the_ground(
FILE: tests/tasks/test_stack_blocks.py
class TestStackBlocks (line 13) | class TestStackBlocks:
method test_terminates_when_any_block_is_on_the_ground (line 14) | def test_terminates_when_any_block_is_on_the_ground(
FILE: tests/tasks/test_tasks.py
class TestEnvs (line 19) | class TestEnvs:
method test_terminates_when_robot_out_of_bounds (line 20) | def test_terminates_when_robot_out_of_bounds(
FILE: tests/test_action_modes.py
function test_join_position_absolute_block_until_reached (line 18) | def test_join_position_absolute_block_until_reached():
function test_floating_base (line 47) | def test_floating_base():
class TestActionModeStability (line 72) | class TestActionModeStability:
method run_simulation (line 76) | def run_simulation(self, env: BiGymEnv, action: np.ndarray):
method test_action_space_is_stable (line 81) | def test_action_space_is_stable(self, action_mode: ActionMode):
method test_action_space_raises_when_beyond_bounds (line 88) | def test_action_space_raises_when_beyond_bounds(self, action_mode: Act...
FILE: tests/test_demo_store.py
function temp_demo_store (line 42) | def temp_demo_store():
class TestDemoStore (line 49) | class TestDemoStore:
method record_demo (line 53) | def record_demo(
method generate_demos (line 69) | def generate_demos(
method test_upload_and_download_of_a_demo (line 103) | def test_upload_and_download_of_a_demo(self, temp_demo_store):
method _test_upload_and_download_multiple_demos (line 115) | def _test_upload_and_download_multiple_demos(
method test_upload_and_download_of_demos (line 161) | def test_upload_and_download_of_demos(self, temp_demo_store):
method test_upload_and_download_of_demos_with_multiple_envs (line 170) | def test_upload_and_download_of_demos_with_multiple_envs(self, temp_de...
method test_upload_and_download_of_demos_with_multiple_action_modes (line 179) | def test_upload_and_download_of_demos_with_multiple_action_modes(
method test_upload_and_download_of_demos_with_multiple_obs_modes (line 190) | def test_upload_and_download_of_demos_with_multiple_obs_modes(
method test_correct_file_structure (line 201) | def test_correct_file_structure(self, temp_demo_store):
method test_get_demo_with_new_observations (line 238) | def test_get_demo_with_new_observations(self, temp_demo_store):
method test_retrieve_n_demos (line 285) | def test_retrieve_n_demos(self, temp_demo_store):
method test_implicit_saving_of_lightweight_demos (line 314) | def test_implicit_saving_of_lightweight_demos(self, temp_demo_store):
method test_exception_thrown_if_demos_do_not_exist (line 319) | def test_exception_thrown_if_demos_do_not_exist(self, temp_demo_store):
method test_exception_thrown_if_lightweight_demos_do_not_exist (line 328) | def test_exception_thrown_if_lightweight_demos_do_not_exist(self, temp...
method test_exception_thrown_if_too_many_demos_requested (line 337) | def test_exception_thrown_if_too_many_demos_requested(self, temp_demo_...
function _generate_simple_demo (line 344) | def _generate_simple_demo():
FILE: tests/test_demos.py
function assert_timesteps_equal (line 20) | def assert_timesteps_equal(d1: Demo, d2: Demo, atol=1e-6) -> None:
class TestDemos (line 41) | class TestDemos:
method record_demo (line 45) | def record_demo(env: BiGymEnv, recorder: DemoRecorder, length: int = 10):
method assert_replay_observations (line 55) | def assert_replay_observations(env: BiGymEnv, demo: Demo, atol=1e-6) -...
method test_save_and_load_demo (line 63) | def test_save_and_load_demo(self, env_class, action_mode):
function test_action_conversion (line 74) | def test_action_conversion():
function test_demo_env_conversion (line 91) | def test_demo_env_conversion():
function test_save_and_load_lightweight_demo (line 132) | def test_save_and_load_lightweight_demo():
function test_recreation_from_lightweight_demo (line 148) | def test_recreation_from_lightweight_demo():
function test_long_running_demo (line 198) | def test_long_running_demo():
FILE: tests/test_envs.py
class TestEnvs (line 25) | class TestEnvs:
method _assert_observations (line 26) | def _assert_observations(self, observation_space: spaces.Dict, observa...
method _assert_step_data (line 32) | def _assert_step_data(self, observation_space, obs, rew, term, trunc, ...
method _are_observations_equal (line 40) | def _are_observations_equal(obs1, obs2):
method test_can_step_with_floating_base (line 44) | def test_can_step_with_floating_base(
method test_can_step_without_floating_base (line 58) | def test_can_step_without_floating_base(
method test_can_step_and_render_human_mode (line 72) | def test_can_step_and_render_human_mode(
method test_can_step_and_render_rgb_array_mode (line 81) | def test_can_step_and_render_rgb_array_mode(
method test_can_get_pixel_observations (line 92) | def test_can_get_pixel_observations(
method test_seed_generation (line 119) | def test_seed_generation(
method test_reset_with_seed (line 136) | def test_reset_with_seed(
method test_correct_task_name_in_vr_env (line 154) | def test_correct_task_name_in_vr_env(
FILE: tests/test_observations.py
class TestObservations (line 25) | class TestObservations:
method test_visual_observations_exist (line 28) | def test_visual_observations_exist(self, rgb, depth, resolution):
function test_no_visual_observations (line 53) | def test_no_visual_observations():
function test_camera_pose_config (line 64) | def test_camera_pose_config():
FILE: tests/test_unstable_simulation.py
function run_simulation (line 21) | def run_simulation(
function test_unstable_simulation_warns (line 38) | def test_unstable_simulation_warns():
function test_unstable_simulation_is_truncated (line 46) | def test_unstable_simulation_is_truncated():
function test_unstable_simulation_consecutive_warnings (line 55) | def test_unstable_simulation_consecutive_warnings():
function test_unstable_simulation_non_consecutive_warnings (line 66) | def test_unstable_simulation_non_consecutive_warnings():
function test_gripper_model_is_stable (line 87) | def test_gripper_model_is_stable():
FILE: tools/demo_player/demo_converter_window.py
class DemoConverterWindow (line 18) | class DemoConverterWindow(BaseWindow):
method __init__ (line 21) | def __init__(self):
method _setup_ui (line 27) | def _setup_ui(self):
method _re_record (line 88) | def _re_record(self):
method _convert (line 91) | def _convert(self):
method _process_demos (line 98) | def _process_demos(self, demo_converter: Callable[[Demo], Demo] = None):
method _update_progress (line 125) | def _update_progress(self, current, total):
method _update_metadata (line 129) | def _update_metadata(self, metadata: Metadata):
method _start_processing (line 136) | def _start_processing(self):
method _finish_processing (line 141) | def _finish_processing(self):
method _select_directory_callback (line 147) | def _select_directory_callback(self):
method _on_target_dir_selected (line 150) | def _on_target_dir_selected(self, target_path: Path):
method _set_target_dir (line 154) | def _set_target_dir(self, target_path: Path):
method show (line 158) | def show(self, source_dir: Path):
method _show_window (line 166) | def _show_window(self):
FILE: tools/demo_player/demo_player_rendering.py
class DemoPlayerRenderer (line 14) | class DemoPlayerRenderer(BiGymRenderer):
method __init__ (line 21) | def __init__(self, mojo: Mojo):
method _get_viewer (line 26) | def _get_viewer(self, render_mode: Optional[str] = None):
method close (line 31) | def close(self):
method set_demo_data (line 36) | def set_demo_data(self, demo_info: DemoStep, actual_info: DemoStep):
class DemoPlayerWindowViewer (line 41) | class DemoPlayerWindowViewer(BiGymWindowViewer):
method __init__ (line 44) | def __init__(
method set_step_data (line 54) | def set_step_data(self, demo_info: DemoStep, actual_info: DemoStep):
method _create_overlay (line 59) | def _create_overlay(self):
method _add_step_info (line 69) | def _add_step_info(self, position, step: DemoStep):
method _format_value (line 77) | def _format_value(self, value) -> str:
method _float_formatter (line 86) | def _float_formatter(value):
FILE: tools/demo_player/demo_player_window.py
class DemosTableRow (line 25) | class DemosTableRow:
class DemosTable (line 36) | class DemosTable:
method __init__ (line 39) | def __init__(self):
method populate (line 85) | def populate(self, demo_files: list[Path]):
method clean (line 91) | def clean(self):
method get_selected_demos (line 97) | def get_selected_demos(self) -> list[Path]:
method update_demo_data (line 105) | def update_demo_data(
method _add_row (line 122) | def _add_row(self, demo_file: Path):
method _row_selected_callback (line 168) | def _row_selected_callback(self, sender, app_data, user_data: int):
class DemoPlayerWindow (line 175) | class DemoPlayerWindow(BaseWindow):
method __init__ (line 184) | def __init__(self):
method _setup_ui (line 191) | def _setup_ui(self):
method on_close (line 221) | def on_close(self):
method _stop_demo_replay (line 225) | def _stop_demo_replay(self):
method _start_demo_replay (line 231) | def _start_demo_replay(self, demo_path: Path):
method _run_demo (line 241) | def _run_demo(self, demo: Demo):
method _run_env (line 245) | def _run_env(self, demo: Demo):
method _select_directory_callback (line 283) | def _select_directory_callback(self):
method _on_directory_selected (line 286) | def _on_directory_selected(self, selected_path: Path):
method _update_files_list (line 290) | def _update_files_list(self):
method _replay_selected_callback (line 298) | def _replay_selected_callback(self):
method _pull_demos_callback (line 308) | def _pull_demos_callback():
method _get_frequency (line 311) | def _get_frequency(self) -> int:
method _current_dir (line 315) | def _current_dir(self) -> Optional[Path]:
method _current_dir (line 324) | def _current_dir(self, value):
FILE: tools/demo_player/main.py
class DemoPlayer (line 8) | class DemoPlayer:
method __init__ (line 11) | def __init__(self):
FILE: tools/demo_recorder/demo_recorder_window.py
class DemoRecorder (line 27) | class DemoRecorder:
method __init__ (line 32) | def __init__(self, target_dir: Path):
method is_running (line 48) | def is_running(self) -> bool:
method target_dir (line 53) | def target_dir(self) -> Path:
method target_dir (line 58) | def target_dir(self, value: Path):
method set_env_cls (line 62) | def set_env_cls(self, env_cls_name: str):
method toggle_floating_dof (line 67) | def toggle_floating_dof(self, dof_name: str, active: bool):
method get_active_floating_dofs (line 72) | def get_active_floating_dofs(self) -> list[PelvisDof]:
method get_floating_dofs (line 76) | def get_floating_dofs(self) -> dict[PelvisDof, bool]:
method get_robots (line 80) | def get_robots(self) -> list[str]:
method set_robot (line 84) | def set_robot(self, robot_name: str):
method get_control_profiles (line 88) | def get_control_profiles(self) -> list[str]:
method set_control_profile (line 92) | def set_control_profile(self, profile_name: str):
method get_env_names (line 97) | def get_env_names(filter_string: str = "") -> list[str]:
method start_viewer (line 104) | def start_viewer(self, on_started: Optional[Callable] = None) -> bool:
method _run_vr_viewer (line 140) | def _run_vr_viewer(
method stop_viewer (line 164) | def stop_viewer(self, on_stopped: Optional[Callable] = None):
class DemoRecorderWindow (line 176) | class DemoRecorderWindow(BaseWindow):
method __init__ (line 179) | def __init__(self):
method _setup_ui (line 184) | def _setup_ui(self):
method _filter_env_names (line 240) | def _filter_env_names(self, sender, filter_string: str = ""):
method _configure_recorder (line 244) | def _configure_recorder(self):
method _change_target_dir (line 251) | def _change_target_dir(self):
method _set_target_dir (line 254) | def _set_target_dir(self, target_dir: Path):
method _start (line 258) | def _start(self):
method _on_started (line 267) | def _on_started(self, popup: int):
method _stop (line 272) | def _stop(self):
method _on_stopped (line 278) | def _on_stopped(self, popup: int):
method _exit (line 289) | def _exit():
FILE: tools/demo_recorder/main.py
class DemoRecorder (line 7) | class DemoRecorder:
method __init__ (line 10) | def __init__(self):
FILE: tools/shared/base_window.py
class BaseWindow (line 9) | class BaseWindow(ABC):
method __init__ (line 12) | def __init__(self):
method _setup_ui (line 17) | def _setup_ui(self):
method _select_directory (line 21) | def _select_directory(
method _show_popup (line 36) | def _show_popup(
method on_close (line 74) | def on_close(self):
FILE: tools/shared/primary_window.py
class PrimaryWindow (line 9) | class PrimaryWindow:
method __init__ (line 12) | def __init__(
FILE: tools/shared/settings_shelf.py
class SettingsShelf (line 10) | class SettingsShelf:
method __init__ (line 16) | def __init__(self, file_name: str):
method get (line 26) | def get(self, key: str, default: Any) -> Any:
method set (line 31) | def set(self, key: str, value: Any):
FILE: tools/shared/utils.py
class ReplayMode (line 66) | class ReplayMode(Enum):
function get_demos_in_dir (line 135) | def get_demos_in_dir(directory: Path) -> list[Path]:
function select_directory (line 141) | def select_directory(default_path: Union[Path, str], callback: Callable[...
function show_popup (line 155) | def show_popup(
FILE: vr/ik/h1_upper_body_ik.py
class Pose (line 39) | class Pose:
class H1UpperBodyIK (line 47) | class H1UpperBodyIK:
method __init__ (line 56) | def __init__(self, env: BiGymEnv):
method solve (line 157) | def solve(
method _generate_ee_actuators (line 205) | def _generate_ee_actuators(self, site: str, origin: str):
method _get_site_quaternion (line 237) | def _get_site_quaternion(self, site: mjcf.Element) -> Quaternion:
FILE: vr/viewer/__init__.py
class Side (line 5) | class Side(enum.IntEnum):
FILE: vr/viewer/control_profiles/control_profile.py
class ControlProfile (line 18) | class ControlProfile(ABC):
method __init__ (line 21) | def __init__(self, env: BiGymEnv):
method get_next_action (line 26) | def get_next_action(
method reset (line 42) | def reset(self):
method _get_controller_pose (line 47) | def _get_controller_pose(
method _get_hmd_pose (line 56) | def _get_hmd_pose(
FILE: vr/viewer/control_profiles/h1_floating.py
class H1Floating (line 15) | class H1Floating(ControlProfile):
method __init__ (line 31) | def __init__(self, env: BiGymEnv):
method get_next_action (line 38) | def get_next_action(
FILE: vr/viewer/control_profiles/universal_floating.py
class UniversalFloating (line 15) | class UniversalFloating(ControlProfile):
method __init__ (line 31) | def __init__(self, env: BiGymEnv):
method get_next_action (line 54) | def get_next_action(
method _get_base_control (line 71) | def _get_base_control(self, turn: float, forward: float, steps: int) -...
method _get_joints_control (line 91) | def _get_joints_control(self, value: float, steps: int) -> np.ndarray:
method _joystick_value (line 108) | def _joystick_value(self, value: float) -> float:
method _toggle_control_mode (line 112) | def _toggle_control_mode(self):
method _toggle_target_joint (line 116) | def _toggle_target_joint(self):
method _indicate_control_mode (line 124) | def _indicate_control_mode(self):
FILE: vr/viewer/controller.py
class ControllerState (line 32) | class ControllerState:
method __init__ (line 35) | def __init__(self):
method a_clicked (line 54) | def a_clicked(self):
method b_clicked (line 59) | def b_clicked(self):
method trigger_clicked (line 64) | def trigger_clicked(self):
class Controller (line 69) | class Controller:
method __init__ (line 72) | def __init__(
method set_context (line 84) | def set_context(self, context: XRContextObject):
method update (line 88) | def update(self, space_offset: Posef):
method vibrate (line 105) | def vibrate(self):
FILE: vr/viewer/full_screen_renderer.py
class VRFullScreenRenderer (line 37) | class VRFullScreenRenderer:
method __init__ (line 40) | def __init__(self, width: int, height: int):
method _create_shader (line 60) | def _create_shader() -> int:
method _create_texture (line 73) | def _create_texture() -> int:
method _update_texture (line 84) | def _update_texture(texture_id, width, height, data):
method render (line 98) | def render(self, side: Side, pixels: np.array):
FILE: vr/viewer/pyopenxr_to_mujoco_converter.py
function vector_from_pyopenxr (line 8) | def vector_from_pyopenxr(xr_vector: [Vector3f, np.array]) -> np.ndarray:
function quaternion_from_pyopenxr (line 25) | def quaternion_from_pyopenxr(xr_quaternion: Quaternionf) -> np.ndarray:
function camera_axes_from_pyopenxr (line 34) | def camera_axes_from_pyopenxr(
FILE: vr/viewer/vr_mujoco_renderer.py
class Renderer (line 20) | class Renderer(mujoco.Renderer):
method __init__ (line 23) | def __init__(
class VRMujocoRenderer (line 41) | class VRMujocoRenderer:
method __init__ (line 44) | def __init__(self, mojo: Mojo, height: int, width: int):
method _scene (line 66) | def _scene(self) -> mujoco.MjvScene:
method set_context (line 69) | def set_context(self, context: XRContextObject):
method show_stats (line 74) | def show_stats(
method add_marker (line 91) | def add_marker(self, **marker_params):
method render (line 95) | def render(self, frame_state: FrameState, offset: Posef):
method _render_mujoco_env (line 103) | def _render_mujoco_env(self) -> np.array:
method _sync_mujoco_vr_cameras_with_views (line 110) | def _sync_mujoco_vr_cameras_with_views(self, views: list[View], offset...
method _add_marker_to_scene (line 141) | def _add_marker_to_scene(self, marker: dict):
FILE: vr/viewer/vr_viewer.py
class Resolution (line 30) | class Resolution(Enum):
class VRViewerStats (line 39) | class VRViewerStats:
class Countdown (line 51) | class Countdown:
method __init__ (line 54) | def __init__(self, delay: int):
method step (line 58) | def step(self):
method is_up (line 64) | def is_up(self) -> bool:
class VRViewer (line 69) | class VRViewer:
method __init__ (line 79) | def __init__(
method _vr_env (line 120) | def _vr_env(self, env_cls: Type[BiGymEnv]) -> Type[BiGymEnv]:
method run (line 153) | def run(
method _get_action (line 186) | def _get_action(self, steps_count: int) -> np.ndarray:
method _handle_input (line 195) | def _handle_input(self, context: XRContextObject):
method _render_frame (line 211) | def _render_frame(self, frame_state: FrameState):
method _start_recording (line 215) | def _start_recording(self):
method _stop_recording (line 224) | def _stop_recording(self):
method _save_recording (line 230) | def _save_recording(self):
method _predict_steps_count (line 236) | def _predict_steps_count(self, frame_state: FrameState) -> int:
method _update_stats (line 244) | def _update_stats(self):
FILE: vr/viewer/xr_context.py
class XRContextObject (line 20) | class XRContextObject(xr.ContextObject):
method __init__ (line 28) | def __init__(
method __enter__ (line 49) | def __enter__(self):
method __exit__ (line 55) | def __exit__(self, exc_type, exc_val, exc_tb):
method frame_loop (line 78) | def frame_loop(self):
FILE: vr/viewer/xr_input.py
class XRInput (line 12) | class XRInput:
method __init__ (line 18) | def __init__(self, context: xr.ContextObject):
method state (line 313) | def state(self) -> list[ControllerState]:
method views (line 318) | def views(self) -> list[View]:
method hmd_pose (line 323) | def hmd_pose(self) -> Posef:
method update (line 327) | def update(self, time: Time):
method _get_action_state_float (line 405) | def _get_action_state_float(self, action: xr.Action, hand: Side) -> fl...
method _get_action_state_bool (line 415) | def _get_action_state_bool(self, action: xr.Action, hand: Side) -> bool:
method _get_action_state_pose (line 425) | def _get_action_state_pose(self, action: xr.Action, hand: Side) -> bool:
method _get_space_pose (line 435) | def _get_space_pose(self, time: Time, space: xr.Space) -> Posef:
method _apply_vibration (line 449) | def _apply_vibration(self, action: xr.Action, hand: Side):
Copy disabled (too large)
Download .json
Condensed preview — 579 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (46,450K chars).
[
{
"path": ".github/workflows/build.yaml",
"chars": 1009,
"preview": "name: build\n\non:\n push:\n branches: [master]\n pull_request:\n branches: [master]\n\njobs:\n bigym:\n runs-on: ubun"
},
{
"path": ".gitignore",
"chars": 309,
"preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n\n# C extensions\n*.so\n\n# Distribution / packaging\nbin/\nbui"
},
{
"path": ".pre-commit-config.yaml",
"chars": 887,
"preview": "repos:\n - repo: https://github.com/pre-commit/pre-commit-hooks\n rev: v4.4.0\n hooks:\n - id: check-yaml\n "
},
{
"path": "CHANGELOG.md",
"chars": 5905,
"preview": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Change"
},
{
"path": "LICENSE",
"chars": 22714,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 19587,
"preview": "<h1>\n <a href=\"#\"><img alt=\"BiGym\" src=\"doc/images/bigym.png\" width=\"100%\"></a>\n</h1>\n\n<p>\n <a href=\"https://github.co"
},
{
"path": "bigym/__init__.py",
"chars": 35,
"preview": "\"\"\"Init.\"\"\"\n\n__version__ = \"4.1.0\"\n"
},
{
"path": "bigym/action_modes.py",
"chars": 10904,
"preview": "\"\"\"Action modes for H1.\"\"\"\nfrom __future__ import annotations\n\nfrom enum import Enum\nfrom typing import TYPE_CHECKING\n\ni"
},
{
"path": "bigym/bigym_env.py",
"chars": 17544,
"preview": "\"\"\"Core BiGym env functionality.\"\"\"\nfrom __future__ import annotations\n\nimport logging\nfrom pathlib import Path\nfrom typ"
},
{
"path": "bigym/bigym_renderer.py",
"chars": 3940,
"preview": "\"\"\"Fix to be able to render to on- and off- screen at the same time.\"\"\"\nimport time\nimport glfw\nimport mujoco\n\nfrom gymn"
},
{
"path": "bigym/const.py",
"chars": 756,
"preview": "\"\"\"A set of common constants.\"\"\"\nfrom __future__ import annotations\n\nfrom enum import Enum, IntEnum\nfrom pathlib import "
},
{
"path": "bigym/envs/__init__.py",
"chars": 12,
"preview": "\"\"\"Init.\"\"\"\n"
},
{
"path": "bigym/envs/cupboards.py",
"chars": 3205,
"preview": "\"\"\"Cupboard interaction tasks.\"\"\"\nfrom abc import ABC\n\nimport numpy as np\n\nfrom bigym.bigym_env import BiGymEnv\nfrom big"
},
{
"path": "bigym/envs/dishwasher.py",
"chars": 1701,
"preview": "\"\"\"Dishwasher interaction tasks.\"\"\"\nfrom abc import ABC\n\nimport numpy as np\n\nfrom bigym.bigym_env import BiGymEnv\nfrom b"
},
{
"path": "bigym/envs/dishwasher_cups.py",
"chars": 4653,
"preview": "\"\"\"Load/unload cups to/from dishwasher.\"\"\"\nfrom abc import ABC\n\nimport numpy as np\nfrom pyquaternion import Quaternion\n\n"
},
{
"path": "bigym/envs/dishwasher_cutlery.py",
"chars": 5991,
"preview": "\"\"\"Load/unload cutlery to/from dishwasher.\"\"\"\nfrom abc import ABC\n\nimport numpy as np\nfrom pyquaternion import Quaternio"
},
{
"path": "bigym/envs/dishwasher_plates.py",
"chars": 4654,
"preview": "\"\"\"Load/unload plates to/from dishwasher.\"\"\"\nfrom abc import ABC\n\nimport numpy as np\nimport quaternion\nfrom pyquaternion"
},
{
"path": "bigym/envs/groceries.py",
"chars": 3270,
"preview": "\"\"\"Groceries tasks.\"\"\"\n\n\nimport numpy as np\n\nfrom bigym.bigym_env import BiGymEnv\nfrom bigym.const import PRESETS_PATH\nf"
},
{
"path": "bigym/envs/manipulation.py",
"chars": 6469,
"preview": "\"\"\"Manipulation tasks.\"\"\"\nfrom abc import ABC\n\nimport numpy as np\nfrom mojo.elements import Body, Geom\nfrom mojo.element"
},
{
"path": "bigym/envs/move_plates.py",
"chars": 3873,
"preview": "\"\"\"Set of plate moving tasks.\"\"\"\nfrom abc import ABC\n\nimport numpy as np\nfrom gymnasium import spaces\nfrom pyquaternion "
},
{
"path": "bigym/envs/pick_and_place.py",
"chars": 10696,
"preview": "\"\"\"Pick and place tasks.\"\"\"\n\nimport numpy as np\nfrom pyquaternion import Quaternion\n\nfrom bigym.bigym_env import BiGymEn"
},
{
"path": "bigym/envs/presets/cabinet.yaml",
"chars": 118,
"preview": "# Static cabinet\nprops:\n - type: BaseCabinet\n position: [1.2, 0, 0]\n euler: [0, 0, -90]\n panel_enable: true\n"
},
{
"path": "bigym/envs/presets/cabinet_door.yaml",
"chars": 154,
"preview": "# Base cabinets with door\nprops:\n - type: BaseCabinet\n position: [1.2, 0, 0]\n euler: [0, 0, -90]\n door_left_en"
},
{
"path": "bigym/envs/presets/cabinet_hob.yaml",
"chars": 173,
"preview": "# Base cabinet with hob\nprops:\n - type: BaseCabinet\n position: [1.2, 0, 0]\n euler: [0, 0, -90]\n door_left_enab"
},
{
"path": "bigym/envs/presets/counter_base_2.yaml",
"chars": 272,
"preview": "# 2 base cabinets\nprops:\n - type: BaseCabinet\n position: [1.1, 0, 0]\n euler: [0, 0, -90]\n shelf_enable: true\n "
},
{
"path": "bigym/envs/presets/counter_base_2_hob.yaml",
"chars": 302,
"preview": "# 2 base cabinets with hob\nprops:\n - type: BaseCabinet\n position: [1.1, 0, 0]\n euler: [0, 0, -90]\n shelf_enabl"
},
{
"path": "bigym/envs/presets/counter_base_wall_1x1.yaml",
"chars": 260,
"preview": "# 1 base and 1 wall cabinet\nprops:\n - type: BaseCabinet\n position: [1.2, 0, 0]\n euler: [0, 0, -90]\n door_left_"
},
{
"path": "bigym/envs/presets/counter_base_wall_2x2.yaml",
"chars": 241,
"preview": "# 2 base and 2 wall cabinets\ninclude:\n - counter_base_2.yaml\nprops:\n - type: WallCabinet\n position: [1.1, 0, 0]\n "
},
{
"path": "bigym/envs/presets/counter_base_wall_3x1.yaml",
"chars": 597,
"preview": "# 3 base and 1 wall cabinets\nprops:\n - type: BaseCabinet\n position: [1.2, 0, 0]\n euler: [ 0, 0, -90 ]\n big_dra"
},
{
"path": "bigym/envs/presets/counter_dishwasher.yaml",
"chars": 297,
"preview": "# Dishwasher with kitchen counter\nprops:\n - type: Dishwasher\n position: [1, 0, 0]\n euler: [0, 0, -90]\n - type: B"
},
{
"path": "bigym/envs/presets/counter_dishwasher_cutlery_cabinet.yaml",
"chars": 305,
"preview": "# Dishwasher with kitchen counter and cabinet with cutlery tray\ninclude:\n - counter_dishwasher.yaml\nprops:\n - type: Ba"
},
{
"path": "bigym/envs/presets/counter_dishwasher_wall_cabinet.yaml",
"chars": 196,
"preview": "# Dishwasher with kitchen counter and wall cabinet\ninclude:\n - counter_dishwasher.yaml\nprops:\n - type: WallCabinet\n "
},
{
"path": "bigym/envs/presets/dishwasher.yaml",
"chars": 90,
"preview": "# Dishwasher\nprops:\n - type: Dishwasher\n position: [1.2, 0, 0]\n euler: [0, 0, -90]\n"
},
{
"path": "bigym/envs/presets/move_plates.yaml",
"chars": 215,
"preview": "# Table for the \"move plates\" task\nprops:\n - type: Table\n position: [0.7, 0, 0]\n euler: [0, 0, -90]\n - type: Dis"
},
{
"path": "bigym/envs/presets/stack_blocks.yaml",
"chars": 177,
"preview": "# Two tables for the \"stack blocks\" task\nprops:\n - type: Table\n position: [0.7, 0, 0]\n euler: [0, 0, -90]\n - typ"
},
{
"path": "bigym/envs/props/__init__.py",
"chars": 12,
"preview": "\"\"\"Init.\"\"\"\n"
},
{
"path": "bigym/envs/props/cabintets.py",
"chars": 5370,
"preview": "\"\"\"Modular cabinets.\"\"\"\nfrom abc import ABC\nfrom pathlib import Path\nfrom typing import Any\n\nimport numpy as np\nfrom dm_"
},
{
"path": "bigym/envs/props/cutlery.py",
"chars": 760,
"preview": "\"\"\"Cutlery props.\"\"\"\nfrom pathlib import Path\n\n\nfrom bigym.const import ASSETS_PATH\nfrom bigym.envs.props.prop import Ki"
},
{
"path": "bigym/envs/props/dishwasher.py",
"chars": 3606,
"preview": "\"\"\"Dishwasher.\"\"\"\nfrom pathlib import Path\nfrom typing import Optional\n\nimport numpy as np\nfrom mojo import Mojo\nfrom mo"
},
{
"path": "bigym/envs/props/holders.py",
"chars": 775,
"preview": "\"\"\"Utensil holder.\"\"\"\nfrom abc import ABC\nfrom pathlib import Path\n\nfrom mojo.elements import Geom\n\nfrom bigym.const imp"
},
{
"path": "bigym/envs/props/items.py",
"chars": 2750,
"preview": "\"\"\"Different pickable items.\"\"\"\nfrom pathlib import Path\nfrom typing import Any\n\nfrom dm_control import mjcf\nfrom mujoco"
},
{
"path": "bigym/envs/props/kitchenware.py",
"chars": 892,
"preview": "\"\"\"Kitchenware.\"\"\"\nfrom pathlib import Path\n\nfrom bigym.const import ASSETS_PATH\nfrom bigym.envs.props.prop import Kinem"
},
{
"path": "bigym/envs/props/preset.py",
"chars": 3446,
"preview": "\"\"\"Props Preset.\"\"\"\nfrom collections import defaultdict\nfrom pathlib import Path\nfrom typing import Optional, Callable, "
},
{
"path": "bigym/envs/props/prop.py",
"chars": 5701,
"preview": "\"\"\"Abstract prop.\"\"\"\nfrom abc import abstractmethod, ABC\nfrom pathlib import Path\nfrom typing import Union, Iterable, Op"
},
{
"path": "bigym/envs/props/tables.py",
"chars": 494,
"preview": "\"\"\"Tables.\"\"\"\nfrom pathlib import Path\n\n\nfrom bigym.const import ASSETS_PATH\nfrom bigym.envs.props.prop import Collidabl"
},
{
"path": "bigym/envs/reach_target.py",
"chars": 5480,
"preview": "\"\"\"Set of reach target tasks.\"\"\"\nfrom abc import ABC\nfrom dataclasses import dataclass, field\n\nimport numpy as np\nfrom g"
},
{
"path": "bigym/envs/xmls/3D_MODELS_ATTRIBUTION.md",
"chars": 4890,
"preview": "# 3D Models Attribution\n\nThis document provides the attribution details for the 3D models included in this repository. T"
},
{
"path": "bigym/envs/xmls/google_robot/assets/link_base_v.obj",
"chars": 446358,
"preview": "# This file uses centimeters as units for non-parametric coordinates.\n\nmtllib link_base.mtl\nv -0.394271 -0.073010 -0.012"
},
{
"path": "bigym/envs/xmls/google_robot/assets/link_bicep_v.obj",
"chars": 86014,
"preview": "# This file uses centimeters as units for non-parametric coordinates.\n\nmtllib link_bicep.mtl\nv -0.056048 -0.005660 0.000"
},
{
"path": "bigym/envs/xmls/google_robot/assets/link_elbow_v.obj",
"chars": 77613,
"preview": "# This file uses centimeters as units for non-parametric coordinates.\n\nmtllib link_elbow.mtl\nv -0.050750 0.000032 0.0020"
},
{
"path": "bigym/envs/xmls/google_robot/assets/link_finger_base_v.obj",
"chars": 304867,
"preview": "# This file uses centimeters as units for non-parametric coordinates.\n\nmtllib link_finger_base_simplified.mtl\ng default\n"
},
{
"path": "bigym/envs/xmls/google_robot/assets/link_finger_tip_v.obj",
"chars": 245734,
"preview": "# This file uses centimeters as units for non-parametric coordinates.\n\nmtllib link_finger_tip_simplified.mtl\ng default\nv"
},
{
"path": "bigym/envs/xmls/google_robot/assets/link_forearm_v.obj",
"chars": 88236,
"preview": "# This file uses centimeters as units for non-parametric coordinates.\n\nmtllib link_forearm.mtl\nv -0.044986 0.001166 -0.0"
},
{
"path": "bigym/envs/xmls/google_robot/assets/link_gripper_v.obj",
"chars": 120953,
"preview": "# This file uses centimeters as units for non-parametric coordinates.\n\nmtllib link_gripper.mtl\nv 0.000973 -0.040528 0.04"
},
{
"path": "bigym/envs/xmls/google_robot/assets/link_head_pan_v.obj",
"chars": 31548,
"preview": "# This file uses centimeters as units for non-parametric coordinates.\n\nmtllib link_head_pan.mtl\nv 0.085088 -0.055653 0.0"
},
{
"path": "bigym/envs/xmls/google_robot/assets/link_head_tilt_v.obj",
"chars": 168844,
"preview": "# This file uses centimeters as units for non-parametric coordinates.\n\nmtllib link_head_tilt.mtl\nv 0.095931 0.000000 0.0"
},
{
"path": "bigym/envs/xmls/google_robot/assets/link_shoulder_v.obj",
"chars": 91412,
"preview": "# This file uses centimeters as units for non-parametric coordinates.\n\nmtllib link_shoulder.mtl\nv -0.065000 0.081174 0.0"
},
{
"path": "bigym/envs/xmls/google_robot/assets/link_torso_v.obj",
"chars": 130149,
"preview": "# This file uses centimeters as units for non-parametric coordinates.\n\nmtllib link_torso.mtl\nv 0.000000 -0.083185 0.0499"
},
{
"path": "bigym/envs/xmls/google_robot/assets/link_wheel_v.obj",
"chars": 50085,
"preview": "# This file uses centimeters as units for non-parametric coordinates.\n\nmtllib link_wheel.mtl\nv 0.061060 -0.009148 -0.019"
},
{
"path": "bigym/envs/xmls/google_robot/assets/link_wrist_v.obj",
"chars": 62280,
"preview": "# This file uses centimeters as units for non-parametric coordinates.\n\nmtllib link_wrist.mtl\nv -0.040296 -0.017485 0.019"
},
{
"path": "bigym/envs/xmls/google_robot/robot.xml",
"chars": 12214,
"preview": "<?xml version=\"1.0\"?>\n<mujoco model=\"robot\">\n <compiler angle=\"radian\" assetdir=\"assets\" autolimits=\"true\"/>\n <option "
},
{
"path": "bigym/envs/xmls/google_robot/scene.xml",
"chars": 899,
"preview": "<?xml version=\"1.0\"?>\n<mujoco model=\"robot scene\">\n <include file=\"robot.xml\"/>\n <statistic center=\"0 0 0.8\" extent=\"2"
},
{
"path": "bigym/envs/xmls/h1/h1.xml",
"chars": 15212,
"preview": "<?xml version=\"1.0\"?>\n<mujoco model=\"h1\">\n <compiler angle=\"radian\" meshdir=\"assets\" autolimits=\"true\"/>\n <statistic m"
},
{
"path": "bigym/envs/xmls/h1/h1_floating_base.xml",
"chars": 9644,
"preview": "<?xml version=\"1.0\"?>\n<mujoco model=\"h1_floating_base\">\n <compiler angle=\"radian\" meshdir=\"assets\" autolimits=\"true\"/>\n"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/base_link_0.obj",
"chars": 3095641,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.21737600 0.00185100 0.02413300\nv -0.21737600 0.00185100 0.02413300\nv -0.217"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/base_link_1.obj",
"chars": 2085,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.22542400 0.05924700 0.13525000\nv -0.22557600 0.05924700 0.13601500\nv -0.226"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/base_link_2.obj",
"chars": 2399,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.19196800 0.01517200 0.16000000\nv -0.19196800 0.01517200 0.16000000\nv -0.191"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/base_link_3.obj",
"chars": 904,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.25113700 -0.00259000 0.11351300\nv -0.25713700 -0.00259000 0.11351300\nv -0.2"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/base_link_4.obj",
"chars": 15958,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.23966700 -0.04703000 0.09720000\nv -0.23966700 -0.04703000 0.09720000\nv -0.2"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/base_link_5.obj",
"chars": 3183264,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.03050000 -0.14328000 0.02840000\nv 0.03050000 -0.14328000 0.02840000\nv 0.0305"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/base_link_6.obj",
"chars": 1997,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.09356300 0.12460800 0.16074700\nv -0.09256300 0.12434000 0.16074700\nv -0.091"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/base_link_7.obj",
"chars": 36652,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.09143700 0.16749700 0.03440000\nv -0.09143700 0.16749700 0.03440000\nv -0.091"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/laser.obj",
"chars": 130243,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.03192900 -0.01433600 0.00800000\nv -0.03192900 -0.01433600 0.00800000\nv -0.0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_arm_l0_0.obj",
"chars": 122619,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.01012500 -0.01712500 0.01925000\nv -0.01012500 -0.01712500 0.01925000\nv -0.0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_arm_l0_1.obj",
"chars": 22154,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.01500000 0.01480000 0.01375000\nv 0.01500000 0.01480000 0.01375000\nv 0.015000"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_arm_l0_2.obj",
"chars": 1331640,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.01500000 0.01480000 0.01375000\nv 0.01500000 0.01480000 0.01375000\nv 0.015000"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_arm_l1_0.obj",
"chars": 14982,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.01550000 -0.01470000 -0.00900000\nv -0.01550000 -0.01470000 -0.00900000\nv -0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_arm_l1_1.obj",
"chars": 469728,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.01764200 -0.01902400 -0.01300000\nv 0.01764200 -0.01902400 -0.01300000\nv 0.01"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_arm_l2_0.obj",
"chars": 14777,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.01600000 0.01750000 -0.00900000\nv -0.01600000 0.01750000 -0.00900000\nv -0.0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_arm_l2_1.obj",
"chars": 430961,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.02167500 0.02167500 -0.01300000\nv 0.02167500 0.02167500 -0.01300000\nv 0.0216"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_arm_l3_0.obj",
"chars": 14258,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.01725000 0.02100000 -0.00900000\nv -0.01725000 0.02100000 -0.00900000\nv 0.01"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_arm_l3_1.obj",
"chars": 436868,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.02159200 -0.02297400 -0.01300000\nv 0.02159200 -0.02297400 -0.01300000\nv 0.02"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_arm_l4_0.obj",
"chars": 14743,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.01850000 -0.02300000 -0.00900000\nv 0.01850000 -0.02300000 -0.00900000\nv -0.0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_arm_l4_1.obj",
"chars": 404802,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.01850000 -0.02300000 -0.00900000\nv -0.01850000 -0.02300000 -0.00900000\nv 0.0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_aruco_inner_wrist.obj",
"chars": 14105,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.01500000 0.01300000 -0.00025000\nv -0.01500000 0.01300000 -0.00025000\nv -0.0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_aruco_left_base.obj",
"chars": 14078,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.03000000 0.02800000 -0.00025000\nv -0.03000000 0.02800000 -0.00025000\nv -0.0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_aruco_right_base.obj",
"chars": 14078,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.03000000 0.02800000 -0.00025000\nv -0.03000000 0.02800000 -0.00025000\nv -0.0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_aruco_shoulder.obj",
"chars": 14066,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.02000000 0.01800000 0.00000000\nv 0.02000000 0.01800000 0.00000000\nv 0.020000"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_aruco_top_wrist.obj",
"chars": 14105,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.01300000 -0.01500000 -0.00025000\nv -0.01300000 -0.01500000 -0.00025000\nv -0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_gripper_0.obj",
"chars": 1143420,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.01475000 0.00000000 -0.01200000\nv -0.01475000 0.00000000 -0.01450000\nv -0.01"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_gripper_1.obj",
"chars": 1051603,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.01475000 0.04175000 -0.04989200\nv 0.01475000 0.04175000 -0.04989200\nv 0.0147"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_gripper_finger_left_0.obj",
"chars": 22879,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.19558400 0.01931900 -0.00650000\nv 0.19558400 0.01931900 -0.00650000\nv 0.1955"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_gripper_finger_left_1.obj",
"chars": 9584,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.18196500 0.01025900 -0.00650000\nv 0.18196500 0.01025900 -0.00650000\nv 0.1821"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_gripper_finger_right_0.obj",
"chars": 24354,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.19558400 -0.01931900 -0.00650000\nv -0.19558400 -0.01931900 -0.00650000\nv -0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_gripper_finger_right_1.obj",
"chars": 9827,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.18196500 -0.01025900 -0.00650000\nv -0.18196500 -0.01025900 -0.00650000\nv -0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_head_1.obj",
"chars": 677456,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.01922600 0.06983300 0.03994400\nv -0.01922600 0.06983300 0.03994400\nv -0.019"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_head_10.obj",
"chars": 2003181,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.02250000 -0.00450700 0.03456700\nv -0.02250000 -0.00450700 0.03456700\nv -0.0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_head_11.obj",
"chars": 3227756,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.02336900 -0.02361500 0.00000000\nv 0.02336900 -0.02361500 0.00000000\nv 0.0233"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_head_2.obj",
"chars": 11722,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.01525100 0.07657200 0.01095400\nv -0.01525100 0.07657200 0.01095400\nv -0.015"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_head_3.obj",
"chars": 19017,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.05541000 0.09203400 0.03401200\nv 0.05541000 0.09203400 0.03401200\nv 0.055410"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_head_4.obj",
"chars": 19757,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.01520500 0.09203400 0.03401200\nv 0.01520500 0.09203400 0.03401200\nv 0.015205"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_head_5.obj",
"chars": 4222,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.04830200 0.07050100 0.03610400\nv 0.04830200 0.07050100 0.03610400\nv 0.047776"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_head_6.obj",
"chars": 17619,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.03934700 0.06428800 0.04254800\nv 0.03952600 0.06435100 0.04254800\nv 0.039526"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_head_7.obj",
"chars": 53929,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.02713000 0.06495900 0.04254800\nv 0.02713000 0.06495900 0.04254800\nv 0.027130"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_head_8.obj",
"chars": 66461,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.02125600 0.06701700 0.04169200\nv 0.02125600 0.06701700 0.04169200\nv 0.021256"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_head_9.obj",
"chars": 182329,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.02499700 0.00592800 0.05146400\nv -0.02499700 0.00592800 0.05146400\nv -0.024"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_head_pan_0.obj",
"chars": 392224,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.01177800 0.03076200 -0.03971800\nv 0.01160100 0.03076200 -0.04395800\nv 0.0113"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_head_pan_1.obj",
"chars": 732009,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.00594900 -0.00078300 -0.00203500\nv 0.00594900 -0.00078300 -0.00203500\nv 0.00"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_head_tilt_0.obj",
"chars": 959273,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.02225000 -0.08160400 0.02593200\nv 0.02225000 -0.08160400 0.02593200\nv 0.0222"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_head_tilt_1.obj",
"chars": 3335035,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.00245600 0.00521700 0.04876300\nv -0.00245600 0.00521700 0.04876300\nv -0.002"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_left_wheel_0.obj",
"chars": 102609,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.03976100 0.02295600 -0.02540000\nv 0.03976100 0.02295600 -0.02540000\nv 0.0401"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_left_wheel_1.obj",
"chars": 2752890,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.00357400 -0.00159100 -0.07906200\nv -0.00357400 -0.00159100 -0.07906200\nv -0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_lift_0.obj",
"chars": 626506,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.03597200 -0.06583800 0.02235900\nv 0.03597200 -0.06583800 0.02235900\nv 0.0359"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_lift_1.obj",
"chars": 1800,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.01490000 -0.01191100 0.06219100\nv 0.01416800 -0.01264300 0.06219100\nv 0.0139"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_lift_2.obj",
"chars": 4464,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.04095100 0.09480300 0.02384400\nv -0.04095100 0.09480300 0.02384400\nv -0.040"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_lift_3.obj",
"chars": 32215,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.03599500 0.10608700 0.02094000\nv -0.03599500 0.10608700 0.02094000\nv -0.035"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_lift_4.obj",
"chars": 84930,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.02807100 0.11158200 0.02663000\nv -0.02807100 0.11158200 0.02663000\nv -0.028"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_lift_5.obj",
"chars": 14538,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.03651400 0.10572800 0.02063800\nv -0.04500600 0.09983600 0.02061900\nv -0.045"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_lift_6.obj",
"chars": 77732,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.03637000 0.10582700 0.02116800\nv -0.03637000 0.10582700 0.02116800\nv -0.036"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_lift_7.obj",
"chars": 21250,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.11586100 0.12699500 -0.00959200\nv -0.11562000 0.12789500 -0.00959200\nv -0.1"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_lift_8.obj",
"chars": 1886206,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.08212300 0.04051100 -0.02508800\nv -0.08212300 0.04051100 -0.02508800\nv -0.0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_lift_9.obj",
"chars": 2459045,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.13260000 0.09090500 -0.00560900\nv -0.13160500 0.07998000 -0.00560900\nv -0.1"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_mast.obj",
"chars": 8366,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.01309400 0.06500000 -0.01906300\nv -0.01309400 0.06500000 -0.01906300\nv -0.0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_right_wheel_0.obj",
"chars": 102524,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv -0.02295600 -0.03976100 0.02540000\nv -0.02295600 -0.03976100 0.02540000\nv -0.0"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_right_wheel_1.obj",
"chars": 2690869,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.00159100 0.00357400 0.07906200\nv 0.00159100 0.00357400 0.07906200\nv 0.001591"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/link_wrist_yaw.obj",
"chars": 432247,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.00399600 0.01184400 -0.01785000\nv 0.00399600 0.01184400 -0.01785000\nv 0.0039"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/assets/respeaker_base.obj",
"chars": 424068,
"preview": "mtllib material_0.mtl\nusemtl material_0\nv 0.00996400 -0.02114700 -0.00420000\nv 0.00996400 -0.02114700 -0.00420000\nv 0.00"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/scene.xml",
"chars": 995,
"preview": "<?xml version=\"1.0\"?>\n<mujoco model=\"stretch scene\">\n <include file=\"stretch.xml\"/>\n <statistic center=\"0 0 .75\" exten"
},
{
"path": "bigym/envs/xmls/hello_robot_stretch/stretch.xml",
"chars": 23490,
"preview": "<?xml version=\"1.0\"?>\n<mujoco model=\"stretch\">\n <compiler angle=\"radian\" assetdir=\"assets\" autolimits=\"true\"/>\n <optio"
},
{
"path": "bigym/envs/xmls/props/board/assets/board.obj",
"chars": 5890,
"preview": "# Blender 4.1.1\n# www.blender.org\no board\nv -0.136278 -0.000000 -0.185833\nv -0.140566 -0.000000 -0.184684\nv -0.143706 -0"
},
{
"path": "bigym/envs/xmls/props/board/board.xml",
"chars": 1060,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<mujoco model=\"board\">\n <compiler angle=\"radian\" meshdir=\"assets\" texturedir=\"as"
},
{
"path": "bigym/envs/xmls/props/box/assets/box.obj",
"chars": 902,
"preview": "# Blender 4.1.1\n# www.blender.org\no box\nv -0.125000 -0.060000 0.100000\nv 0.125000 -0.060000 0.100000\nv -0.125000 0.06000"
},
{
"path": "bigym/envs/xmls/props/box/box.xml",
"chars": 916,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<mujoco model=\"box\">\n <compiler angle=\"radian\" meshdir=\"assets\" texturedir=\"asse"
},
{
"path": "bigym/envs/xmls/props/cube/cube.xml",
"chars": 456,
"preview": "<?xml version=\"1.0\"?>\n<mujoco model=\"cube\">\n <compiler angle=\"radian\" meshdir=\"assets\" texturedir=\"assets\" autolimits=\""
},
{
"path": "bigym/envs/xmls/props/cutlery/fork/assets/fork.obj",
"chars": 40959,
"preview": "# Blender 4.0.2\n# www.blender.org\no fork\nv -0.004743 -0.082745 0.004729\nv 0.004743 -0.082745 0.004729\nv -0.007004 -0.012"
},
{
"path": "bigym/envs/xmls/props/cutlery/fork/assets/fork_collision_001.obj",
"chars": 9101,
"preview": "# Blender 4.1.1\n# www.blender.org\no fork_collision.001\nv -0.007004 -0.083675 0.004810\nv -0.007004 0.040151 0.004810\nv -0"
},
{
"path": "bigym/envs/xmls/props/cutlery/fork/assets/fork_collision_002.obj",
"chars": 17332,
"preview": "# Blender 4.1.1\n# www.blender.org\no fork_collision.002\nv -0.007004 0.038825 0.004624\nv -0.009665 0.100172 0.024545\nv -0."
},
{
"path": "bigym/envs/xmls/props/cutlery/fork/fork.xml",
"chars": 1080,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<mujoco model=\"fork\">\n <compiler angle=\"radian\" meshdir=\"assets\" texturedir=\"ass"
},
{
"path": "bigym/envs/xmls/props/cutlery/fork/fork_convex.xml",
"chars": 904,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<mujoco model=\"fork\">\n <compiler angle=\"radian\" meshdir=\"assets\" texturedir=\"ass"
},
{
"path": "bigym/envs/xmls/props/cutlery/knife/assets/knife.obj",
"chars": 36031,
"preview": "# Blender 4.0.2\n# www.blender.org\no knife\nv 0.000000 -0.013204 0.002844\nv -0.004389 -0.013204 0.002393\nv -0.005510 -0.01"
},
{
"path": "bigym/envs/xmls/props/cutlery/knife/assets/knife_collision_001.obj",
"chars": 9162,
"preview": "# Blender 4.1.1\n# www.blender.org\no knife_collision.001\nv 0.008428 -0.113885 0.005146\nv 0.008428 -0.008313 0.005146\nv 0."
},
{
"path": "bigym/envs/xmls/props/cutlery/knife/assets/knife_collision_002.obj",
"chars": 9108,
"preview": "# Blender 4.1.1\n# www.blender.org\no knife_collision.002\nv 0.008428 -0.008313 0.002208\nv 0.008428 0.113885 0.002208\nv 0.0"
},
{
"path": "bigym/envs/xmls/props/cutlery/knife/knife.xml",
"chars": 1095,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<mujoco model=\"knife\">\n <compiler angle=\"radian\" meshdir=\"assets\" texturedir=\"as"
},
{
"path": "bigym/envs/xmls/props/cutlery/knife/knife_convex.xml",
"chars": 912,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<mujoco model=\"knife\">\n <compiler angle=\"radian\" meshdir=\"assets\" texturedir=\"as"
},
{
"path": "bigym/envs/xmls/props/cutlery/spoon/assets/spoon.obj",
"chars": 29519,
"preview": "# Blender 4.0.2\n# www.blender.org\no spoon\nv 0.012407 0.041401 -0.000731\nv 0.006309 0.039498 -0.001544\nv -0.000000 0.0388"
},
{
"path": "bigym/envs/xmls/props/cutlery/spoon/assets/spoon_collision_001.obj",
"chars": 20893,
"preview": "# Blender 4.1.1\n# www.blender.org\no spoon_collision.001\nv -0.006924 0.021948 0.009075\nv -0.020862 0.072784 0.009075\nv -0"
},
{
"path": "bigym/envs/xmls/props/cutlery/spoon/assets/spoon_collision_002.obj",
"chars": 15206,
"preview": "# Blender 4.1.1\n# www.blender.org\no spoon_collision.002\nv -0.006924 -0.081208 0.010290\nv -0.006924 0.021948 0.009075\nv -"
},
{
"path": "bigym/envs/xmls/props/cutlery/spoon/spoon.xml",
"chars": 1095,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<mujoco model=\"spoon\">\n <compiler angle=\"radian\" meshdir=\"assets\" texturedir=\"as"
},
{
"path": "bigym/envs/xmls/props/cutlery/spoon/spoon_convex.xml",
"chars": 912,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<mujoco model=\"spoon\">\n <compiler angle=\"radian\" meshdir=\"assets\" texturedir=\"as"
},
{
"path": "bigym/envs/xmls/props/cutlery_tray/assets/cutlery_tray.obj",
"chars": 6685,
"preview": "# Blender 4.0.2\n# www.blender.org\no cutlery_tray\nv -0.257000 0.000000 0.211000\nv -0.238695 0.056000 0.200554\nv -0.257000"
},
{
"path": "bigym/envs/xmls/props/cutlery_tray/assets/cutlery_tray_collision_001.obj",
"chars": 921,
"preview": "# Blender 4.1.1\n# www.blender.org\no cutlery_tray_collision.001\nv -0.257000 0.000000 0.211000\nv -0.257000 0.009391 0.2110"
},
{
"path": "bigym/envs/xmls/props/cutlery_tray/assets/cutlery_tray_collision_002.obj",
"chars": 917,
"preview": "# Blender 4.1.1\n# www.blender.org\no cutlery_tray_collision.002\nv -0.257000 0.000000 0.211000\nv -0.257000 0.056000 0.2110"
},
{
"path": "bigym/envs/xmls/props/cutlery_tray/assets/cutlery_tray_collision_003.obj",
"chars": 925,
"preview": "# Blender 4.1.1\n# www.blender.org\no cutlery_tray_collision.003\nv -0.257000 0.000000 -0.200554\nv -0.257000 0.056000 -0.20"
},
{
"path": "bigym/envs/xmls/props/cutlery_tray/assets/cutlery_tray_collision_004.obj",
"chars": 917,
"preview": "# Blender 4.1.1\n# www.blender.org\no cutlery_tray_collision.004\nv -0.129792 0.009391 0.109057\nv -0.129792 0.056000 0.1090"
},
{
"path": "bigym/envs/xmls/props/cutlery_tray/assets/cutlery_tray_collision_005.obj",
"chars": 925,
"preview": "# Blender 4.1.1\n# www.blender.org\no cutlery_tray_collision.005\nv -0.257000 0.009391 0.211000\nv -0.257000 0.056000 0.2110"
},
{
"path": "bigym/envs/xmls/props/cutlery_tray/assets/cutlery_tray_collision_006.obj",
"chars": 917,
"preview": "# Blender 4.1.1\n# www.blender.org\no cutlery_tray_collision.006\nv 0.238695 0.009391 0.211000\nv 0.238695 0.056000 0.211000"
},
{
"path": "bigym/envs/xmls/props/cutlery_tray/assets/cutlery_tray_collision_007.obj",
"chars": 925,
"preview": "# Blender 4.1.1\n# www.blender.org\no cutlery_tray_collision.007\nv -0.257000 0.009391 0.211000\nv -0.257000 0.056000 0.2110"
},
{
"path": "bigym/envs/xmls/props/cutlery_tray/assets/cutlery_tray_collision_008.obj",
"chars": 925,
"preview": "# Blender 4.1.1\n# www.blender.org\no cutlery_tray_collision.008\nv -0.139128 0.009391 0.211000\nv -0.139128 0.056000 0.2110"
},
{
"path": "bigym/envs/xmls/props/cutlery_tray/assets/cutlery_tray_collision_009.obj",
"chars": 917,
"preview": "# Blender 4.1.1\n# www.blender.org\no cutlery_tray_collision.009\nv 0.128534 0.009391 0.211000\nv 0.128534 0.056000 0.211000"
},
{
"path": "bigym/envs/xmls/props/cutlery_tray/assets/cutlery_tray_collision_010.obj",
"chars": 917,
"preview": "# Blender 4.1.1\n# www.blender.org\no cutlery_tray_collision.010\nv 0.039314 0.009391 0.109057\nv 0.039314 0.056000 0.109057"
},
{
"path": "bigym/envs/xmls/props/cutlery_tray/assets/cutlery_tray_collision_011.obj",
"chars": 925,
"preview": "# Blender 4.1.1\n# www.blender.org\no cutlery_tray_collision.011\nv -0.050007 0.009391 0.109057\nv -0.050007 0.056000 0.1090"
},
{
"path": "bigym/envs/xmls/props/cutlery_tray/cutlery_tray.xml",
"chars": 2834,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<mujoco model=\"cutlery_tray\">\n <compiler angle=\"radian\" meshdir=\"assets\" texture"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack.obj",
"chars": 32366,
"preview": "# Blender 4.0.2\n# www.blender.org\no rack\nv 0.044858 0.000000 0.137500\nv 0.044858 0.015000 0.137500\nv 0.044858 0.000000 -"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_001.obj",
"chars": 2250,
"preview": "# Blender 4.0.2\n# www.blender.org\no rack_collision.001\nv -0.052500 0.085000 0.121000\nv -0.052500 0.010000 0.121000\nv -0."
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_002.obj",
"chars": 2250,
"preview": "# Blender 4.0.2\n# www.blender.org\no rack_collision.002\nv -0.052500 0.085000 0.079000\nv -0.052500 0.010000 0.079000\nv -0."
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_003.obj",
"chars": 2250,
"preview": "# Blender 4.0.2\n# www.blender.org\no rack_collision.003\nv -0.052500 0.085000 0.037000\nv -0.052500 0.010000 0.037000\nv -0."
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_004.obj",
"chars": 2260,
"preview": "# Blender 4.0.2\n# www.blender.org\no rack_collision.004\nv -0.052500 0.085000 -0.005000\nv -0.052500 0.010000 -0.005000\nv -"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_005.obj",
"chars": 2266,
"preview": "# Blender 4.0.2\n# www.blender.org\no rack_collision.005\nv -0.052500 0.085000 -0.047000\nv -0.052500 0.010000 -0.047000\nv -"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_006.obj",
"chars": 2266,
"preview": "# Blender 4.0.2\n# www.blender.org\no rack_collision.006\nv -0.052500 0.085000 -0.089000\nv -0.052500 0.010000 -0.089000\nv -"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_007.obj",
"chars": 2266,
"preview": "# Blender 4.0.2\n# www.blender.org\no rack_collision.007\nv -0.052500 0.085000 -0.131000\nv -0.052500 0.010000 -0.131000\nv -"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_008.obj",
"chars": 2234,
"preview": "# Blender 4.0.2\n# www.blender.org\no rack_collision.008\nv 0.052500 0.085000 0.121000\nv 0.052500 0.010000 0.121000\nv 0.048"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_009.obj",
"chars": 2234,
"preview": "# Blender 4.0.2\n# www.blender.org\no rack_collision.009\nv 0.052500 0.085000 0.079000\nv 0.052500 0.010000 0.079000\nv 0.048"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_010.obj",
"chars": 2234,
"preview": "# Blender 4.0.2\n# www.blender.org\no rack_collision.010\nv 0.052500 0.085000 0.037000\nv 0.052500 0.010000 0.037000\nv 0.048"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_011.obj",
"chars": 2244,
"preview": "# Blender 4.0.2\n# www.blender.org\no rack_collision.011\nv 0.052500 0.085000 -0.005000\nv 0.052500 0.010000 -0.005000\nv 0.0"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_012.obj",
"chars": 2250,
"preview": "# Blender 4.0.2\n# www.blender.org\no rack_collision.012\nv 0.052500 0.085000 -0.047000\nv 0.052500 0.010000 -0.047000\nv 0.0"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_013.obj",
"chars": 2250,
"preview": "# Blender 4.0.2\n# www.blender.org\no rack_collision.013\nv 0.052500 0.085000 -0.089000\nv 0.052500 0.010000 -0.089000\nv 0.0"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_014.obj",
"chars": 2250,
"preview": "# Blender 4.0.2\n# www.blender.org\no rack_collision.014\nv 0.052500 0.085000 -0.131000\nv 0.052500 0.010000 -0.131000\nv 0.0"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_015.obj",
"chars": 2258,
"preview": "# Blender 4.1.1\n# www.blender.org\no rack_collision.015\nv -0.050000 0.007221 -0.092500\nv 0.050000 0.007221 -0.092500\nv -0"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_016.obj",
"chars": 2242,
"preview": "# Blender 4.1.1\n# www.blender.org\no rack_collision.016\nv -0.050000 0.007221 0.082500\nv 0.050000 0.007221 0.082500\nv -0.0"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_017.obj",
"chars": 1089,
"preview": "# Blender 4.1.1\n# www.blender.org\no rack_collision.017\nv 0.044858 0.000000 0.137500\nv 0.044858 0.015000 0.137500\nv 0.044"
},
{
"path": "bigym/envs/xmls/props/dish_drainer/assets/rack_collision_018.obj",
"chars": 1097,
"preview": "# Blender 4.1.1\n# www.blender.org\no rack_collision.018\nv -0.060000 0.000000 0.137500\nv -0.060000 0.015000 0.137500\nv -0."
},
{
"path": "bigym/envs/xmls/props/dish_drainer/dish_drainer.xml",
"chars": 3283,
"preview": "<?xml version=\"1.0\"?>\n<mujoco model=\"dish_drainer\">\n <compiler angle=\"radian\" meshdir=\"assets\" texturedir=\"assets\" auto"
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_bottom_basket_001.obj",
"chars": 942,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_dish_washer_bottom_basket.001\nv -0.056407 -0.078987 0.223038\nv -0.056407 -"
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_bottom_basket_002.obj",
"chars": 934,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_dish_washer_bottom_basket.002\nv -0.056407 -0.078987 0.223038\nv -0.056407 0"
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_bottom_basket_003.obj",
"chars": 942,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_dish_washer_bottom_basket.003\nv -0.056407 -0.078987 -0.219795\nv -0.056407 "
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_bottom_basket_004.obj",
"chars": 934,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_dish_washer_bottom_basket.004\nv 0.018782 -0.078987 0.223038\nv 0.018782 0.0"
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_bottom_basket_005.obj",
"chars": 942,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_dish_washer_bottom_basket.005\nv -0.056407 -0.078987 0.223038\nv -0.056407 0"
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_bottom_basket_006.obj",
"chars": 942,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_dish_washer_bottom_basket.006\nv -0.052859 -0.071039 -0.151054\nv -0.052859 "
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_bottom_basket_007.obj",
"chars": 942,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_dish_washer_bottom_basket.007\nv -0.052859 -0.071039 -0.079866\nv -0.052859 "
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_bottom_basket_008.obj",
"chars": 934,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_dish_washer_bottom_basket.008\nv -0.052859 -0.071039 0.082354\nv -0.052859 0"
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_bottom_basket_009.obj",
"chars": 934,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_dish_washer_bottom_basket.009\nv -0.052859 -0.071039 0.153949\nv -0.052859 0"
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_bottom_basket_010.obj",
"chars": 938,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_dish_washer_bottom_basket.010\nv -0.056407 -0.078987 0.007608\nv -0.056407 0"
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_bottom_basket_011.obj",
"chars": 930,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_dish_washer_bottom_basket.011\nv 0.020859 -0.012610 0.062931\nv 0.020859 0.0"
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_bottom_basket_012.obj",
"chars": 938,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_dish_washer_bottom_basket.012\nv 0.020859 -0.012610 -0.048645\nv 0.020859 0."
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_bottom_basket_013.obj",
"chars": 1948,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_dish_washer_bottom_basket.013\nv 0.021687 0.084962 0.076234\nv 0.012029 0.09"
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_bottom_basket_014.obj",
"chars": 1149,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_dish_washer_bottom_basket.014\nv 0.020859 0.018963 0.062931\nv 0.020859 0.03"
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_bottom_basket_015.obj",
"chars": 998,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_dish_washer_bottom_basket.015\nv 0.042957 0.006152 0.062931\nv 0.042957 0.02"
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_dish_washer_mid_sprinkle.obj",
"chars": 933,
"preview": "# Blender 4.0.2\n# www.blender.org\no collision_dish_washer_mid_sprinkle\nv -0.191648 -0.004318 0.014731\nv -0.191648 0.0056"
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_door_001.obj",
"chars": 909,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_door.001\nv 0.247474 0.114380 0.013827\nv 0.247474 0.487809 0.013827\nv 0.247"
},
{
"path": "bigym/envs/xmls/props/dishwasher/assets/collision/collision_door_003.obj",
"chars": 917,
"preview": "# Blender 4.1.1\n# www.blender.org\no collision_door.003\nv -0.274098 0.114380 0.016822\nv -0.274098 0.487809 0.016822\nv -0."
}
]
// ... and 379 more files (download for full content)
About this extraction
This page contains the full source code of the chernyadev/bigym GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 579 files (75.1 MB), approximately 11.3M tokens, and a symbol index with 811 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.