├── .gitignore ├── README.md ├── __init__.py ├── auto_control.py ├── convert_scenes.py ├── img ├── overview.png ├── printer.gif └── visualizations.png ├── manual_control.py ├── mini_bddl ├── __init__.py ├── actions.py ├── objs.py └── states.py ├── mini_behavior ├── __init__.py ├── actions.py ├── envs │ ├── __init__.py │ ├── auto_env.py │ ├── boxing_books_up_for_storage.py │ ├── cleaning_a_car.py │ ├── cleaning_shoes.py │ ├── cleaning_up_the_kitchen_only.py │ ├── collect_misplaced_items.py │ ├── installing_a_printer.py │ ├── laying_wood_floors.py │ ├── making_tea.py │ ├── moving_boxes_to_storage.py │ ├── navigation.py │ ├── opening_packages.py │ ├── organizing_file_cabinet.py │ ├── preparing_salad.py │ ├── preparing_salad_floorplan.py │ ├── putting_away_dishes_after_cleaning.py │ ├── setting_up_candles.py │ ├── sorting_books.py │ ├── storing_food.py │ ├── thawing_frozen_food.py │ ├── throwing_away_leftovers.py │ ├── throwleftovers_floorplan.py │ ├── transition.py │ ├── two_room_nav.py │ ├── washing_pots_and_pans.py │ └── watering_houseplants.py ├── floorplan.py ├── floorplans │ ├── beechwood_0_int_floor_trav_no_obj_0.png │ ├── beechwood_1_int_floor_trav_no_obj_0.png │ ├── benevolence_0_int_floor_trav_no_obj_0.png │ ├── benevolence_1_int_floor_trav_no_obj_0.png │ ├── benevolence_2_int_floor_trav_no_obj_0.png │ ├── ihlen_0_int_floor_trav_no_obj_0.png │ ├── ihlen_1_int_floor_trav_no_obj_0.png │ ├── init_install_printer.json │ ├── merom_0_int_floor_trav_no_obj_0.png │ ├── merom_1_int_floor_trav_no_obj_0.png │ ├── pomaria_0_int_floor_trav_no_obj_0.png │ ├── pomaria_1_int_floor_trav_no_obj_0.png │ ├── pomaria_2_int_floor_trav_no_obj_0.png │ ├── rs_int_floor_trav_no_obj_0.png │ ├── wainscott_0_int_floor_trav_no_obj_0.png │ └── wainscott_1_int_floor_trav_no_obj_0.png ├── grid.py ├── minibehavior.py ├── objects.py ├── register.py ├── rendering.py ├── roomgrid.py ├── scenes │ ├── beechwood_0_int_floor_trav_no_obj_0.png │ ├── beechwood_1_int_floor_trav_no_obj_0.png │ ├── benevolence_0_int_floor_trav_no_obj_0.png │ ├── benevolence_1_int_floor_trav_no_obj_0.png │ ├── benevolence_2_int_floor_trav_no_obj_0.png │ ├── ihlen_0_int_floor_trav_no_obj_0.png │ ├── ihlen_1_int_floor_trav_no_obj_0.png │ ├── merom_0_int_floor_trav_no_obj_0.png │ ├── merom_1_int_floor_trav_no_obj_0.png │ ├── pomaria_0_int_floor_trav_no_obj_0.png │ ├── pomaria_1_int_floor_trav_no_obj_0.png │ ├── pomaria_2_int_floor_trav_no_obj_0.png │ ├── rs_int_floor_trav_no_obj_0.png │ ├── wainscott_0_int_floor_trav_no_obj_0.png │ └── wainscott_1_int_floor_trav_no_obj_0.png ├── states.py ├── utils │ ├── __init__.py │ ├── get_icon_square.py │ ├── globals.py │ ├── load.py │ ├── object_actions.json │ ├── object_icons │ │ ├── apple.jpg │ │ ├── ashcan.jpg │ │ ├── backpack.jpg │ │ ├── ball.jpg │ │ ├── banana.jpg │ │ ├── basket.jpg │ │ ├── bed.jpg │ │ ├── beef.jpg │ │ ├── bin.jpg │ │ ├── blender.jpg │ │ ├── book.jpg │ │ ├── bow.jpg │ │ ├── box.jpg │ │ ├── bread.jpg │ │ ├── broom.jpg │ │ ├── bucket.jpg │ │ ├── cabinet.jpg │ │ ├── cake.jpg │ │ ├── calculator.jpg │ │ ├── candle.jpg │ │ ├── candy.jpg │ │ ├── car.jpg │ │ ├── carton.jpg │ │ ├── carving_knife.jpg │ │ ├── casserole.jpg │ │ ├── chair.jpg │ │ ├── chicken.jpg │ │ ├── chip.jpg │ │ ├── cleaning_brush.jpg │ │ ├── cookie.jpg │ │ ├── countertop.jpg │ │ ├── date.jpg │ │ ├── document.jpg │ │ ├── dustpan.jpg │ │ ├── egg.jpg │ │ ├── electric_refrigerator.jpg │ │ ├── fish.jpg │ │ ├── folder.jpg │ │ ├── fork.jpg │ │ ├── gym_shoe.jpg │ │ ├── hamburger.jpg │ │ ├── hammer.jpg │ │ ├── hardback.jpg │ │ ├── hardcover.jpg │ │ ├── jar.jpg │ │ ├── jewelry.jpg │ │ ├── juice.jpg │ │ ├── kettle.jpg │ │ ├── knife.jpg │ │ ├── lemon.jpg │ │ ├── lettuce.jpg │ │ ├── marker.jpg │ │ ├── necklace.jpg │ │ ├── notebook.jpg │ │ ├── oatmeal.jpg │ │ ├── olive.jpg │ │ ├── package.jpg │ │ ├── pan.jpg │ │ ├── pen.jpg │ │ ├── pencil.jpg │ │ ├── plate.jpg │ │ ├── plywood.jpg │ │ ├── pop.jpg │ │ ├── pot_plant.jpg │ │ ├── printer.jpg │ │ ├── radish.jpg │ │ ├── rag.jpg │ │ ├── salad.jpg │ │ ├── sandwich.jpg │ │ ├── saw.jpg │ │ ├── scrub_brush.jpg │ │ ├── shelf.jpg │ │ ├── shoe.jpg │ │ ├── shower.jpg │ │ ├── sink.jpg │ │ ├── soap.jpg │ │ ├── sock.jpg │ │ ├── sofa.jpg │ │ ├── soup.jpg │ │ ├── spoon.jpg │ │ ├── stove.jpg │ │ ├── strawberry.jpg │ │ ├── sugar.jpg │ │ ├── table.jpg │ │ ├── tea_bag.jpg │ │ ├── teapot.jpg │ │ ├── toilet.jpg │ │ ├── tomato.jpg │ │ ├── towel.jpg │ │ ├── trash.jpg │ │ ├── vegetable_oil.jpg │ │ ├── water.jpg │ │ └── window.jpg │ ├── object_properties.json │ ├── objects_base.py │ ├── save.py │ ├── scene_to_grid.py │ ├── state_icons │ │ ├── cookable.jpg │ │ ├── dustyable.jpg │ │ ├── freezable.jpg │ │ ├── openable.jpg │ │ ├── sliceable.jpg │ │ ├── soakable.jpg │ │ ├── stainable.jpg │ │ └── toggleable.jpg │ ├── states_base.py │ ├── utils.py │ └── wrappers.py └── window.py ├── scripts ├── load_demos.py ├── train_rl_agent.sh └── visualize_policy.py ├── setup.py └── train_rl_agent.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *__pycache__ 3 | *egg-info 4 | trained_models 5 | .DS_Store 6 | 7 | # PyPI 8 | build/* 9 | dist/* 10 | .idea/ 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mini-BEHAVIOR 2 | Link to paper: https://arxiv.org/abs/2310.01824 3 | 4 | ### MiniGrid Implementation of BEHAVIOR Tasks 5 | ![Screenshot](img/overview.png) 6 | 7 | Mini-BEHAVIOR is a simple and easy-to-use high-speed 3D-gridworld environment 8 | with a high-level action space and a set of implementations of long-horizon, interaction-rich BEHAVIOR tasks. 9 | Mini-BEHAVIOR includes 20 tasks of varying difficulty, 96 objects, 23 states, and 15 actions. 10 | The actions include 3 for navigation (forward, turn left, turn right) and 12 for manipulating objects in the environment 11 | (pick, place, open, close, etc). 12 | The tasks are instantiated in simulated household environments. 13 | 14 | ### Updates 15 | [8/10/2024] 16 | - Mini-BEHAVIOR now supports gymnasium API at the [gymnasium](https://github.com/StanfordVL/mini_behavior/tree/gymnasium) branch. 17 | 18 | ### Environment Setup 19 | * Install gym-mingrid v1.0.3: 20 | ``` 21 | pip install gym-minigrid==1.0.3 22 | ``` 23 | * Install gym v0.21.0: 24 | ``` 25 | pip install setuptools==66.0.0 26 | pip install wheel==0.38.4 27 | pip install gym==0.21.0 28 | ``` 29 | * (Optional) Install stable-baselines3: 30 | ``` 31 | pip install stable-baselines3==1.6.2 32 | ``` 33 | * Install mini-behavior: 34 | ``` 35 | pip install -e . 36 | ``` 37 | 38 | ### Run Code 39 | * To run in interactive mode: 40 | ``` 41 | python manual_control.py 42 | ``` 43 | * Key Bindings: 44 | - `up`: move forward 45 | - `left`: turn left 46 | - `right`: turn right 47 | - `0, 1, 2`: pick up object at the corresponding dimension 48 | - `3, 4, 5`: drop object at the corresponding dimension 49 | - `i`: drop in 50 | - `t`: toggle 51 | - `c`: close 52 | - `o`: open 53 | - `k`: cook 54 | - `s`: slice 55 | * To train a sample RL agent with stable-baseline3 installed: 56 | ``` 57 | python train_rl_agent.py --task InstallingAPrinter 58 | ``` 59 | * Example trained RL agent: 60 |

61 | 62 |

63 | 64 | * To collect human demonstrations, run: 65 | ``` 66 | python manual_control.py --save true 67 | ``` 68 | * An example code for loading the demos is shown in scripts/load_demos.py 69 | 70 | ### Action Space Type 71 | Mini-BH supports two types of action spaces: cartesian and primitive. Environment names that ends with v0 correspond to 72 | primitive actions, while v1 corresponds to cartesian actions. We recommend starting off with primitive actions due to 73 | its simplicity and efficiency. 74 | 75 | ### File Descriptions 76 | * **mini_behavior/actions.py** 77 | * Contains base class for actions 78 | * All action classes defined here 79 | 80 | * **mini_bddl/*.py** 81 | * Contains all implemented states, actions, and mappings based on original BEHAVIOR BDDL Code 82 | 83 | * **mini_behavior/utils/globals.py** 84 | * Defines colors, mappings, etc, used for rendering the grid environment 85 | 86 | * **mini_behavior/minibehavior.py** 87 | * Contains base class for mini grid environment 88 | * Modified to support multiple objects in a tile, generalizability to any actions / states / objects 89 | * Significant changes made to: grid.set, grid.remove, grid.render_tile, grid.render, minigrid.ste 90 | 91 | * **mini_behavior/objects.py** 92 | * Contains base class for GridWorld objects 93 | * All object classes defined here 94 | 95 | * **mini_behavior/utils/states_base.py** 96 | * Contains base classes for states (different classes for absolute and relative states) 97 | 98 | * **mini_behavior/states.py** 99 | * All states defined here, inherited from base classes in states_base.py 100 | 101 | 102 | ### Floor plan to Mini-Behavior Environment 103 | * add image file of floor plan to mini_behavior/scenes directory 104 | * run script to process floor plan and save grid to mini_behavior/grids directory: `python convert_scenes.py --imgs IMG_FILENAMES` 105 | * `floorplan.py` will register the floor plan of each `IMG_FILENAME` as an environment with: 106 | * `id='MiniGrid-IMG_FILENAME-0x0-N1-v0'` 107 | * `entry_point='gym_minigrid.envs:FloorPlanEnv'` 108 | 109 | ### Procedural Mini-Behavior Environment Generation 110 | 111 | - Add a new json file to mini_behavior/floorplans directory 112 | - Write environment configuration file with environment components needed for the mission, we allow roughly defined configurations such different random environments can be procedurally generated. 113 | - An example configuration file `init_install_printer.json` is provided, the configuration file should follow the same format: 114 | ```json 115 | { 116 | "Grid": 117 | { 118 | "mission": str_mission_name, 119 | "auto": { 120 | "room_split_dirs": ["vert", "horz"], # don't need to change 121 | "min_room_dim": 1, # minmum room dimension allowed 122 | "max_num_room": 4 # maximum number of room in the env 123 | }, 124 | "width": 8, # grid width 125 | "height": 8, # grid height 126 | }, 127 | "agents": 128 | { 129 | "pos": null, # agent initial position, random generate if null 130 | "dir": null # agent initial direction, 131 | random generate if null 132 | }, 133 | "rooms": 134 | { 135 | "num": 1, # number of rooms in the env 136 | "initial": 137 | [ 138 | { 139 | "top": null, # top left cell x,y coordinates of the room, [x, y], (exclude the walls) 140 | "size": null, # size of the room, [width, height],(exclude the walls) 141 | "furnitures": 142 | { 143 | "num": 3, # number of furnitrues 144 | "initial": 145 | [ 146 | # first furniture description 147 | { 148 | "type": "printer", # type of the furniture 149 | "state": [["toggleable", 0]], # initial state of the furniture [[state, 0/1]], for not specified states for the furniture, random generate 0 or 1 150 | "pos": null, # position of the furniture 151 | "objs": { 152 | "num": 1, # number of objects in the furniture 153 | "initial": 154 | [ 155 | { 156 | "type": "book", # type of the object 157 | "state": [["dustyable", 1]], # initial state of the furniture [[state, 0/1]], for not specified states for the furniture, random generate 0 or 1 158 | "pos": null, # initial position of the object 159 | "objs": null # 160 | } 161 | ] 162 | } # objects on top of the furniture 163 | }, 164 | ... # 2 more furniture descriptions, or if less than 2, random generate till 3 rooms 165 | ] 166 | } 167 | } 168 | ``` 169 | - Call `python auto_control.py --seed 100 --auto_env_config /path/to/config.json`, replace the 100 with different seed number to allow different procedural generations, and replace `/path/to/config.json` with the path to the json file, such as `'mini_behavior/floorplans/init_install_printer.json'`. 170 | - After calling the command, a random generated grid will show up, when pressing `backspace`, we can regenearte the environment. 171 | 172 | ### References 173 | ``` 174 | @article{jin2023minibehavior, 175 | title={Mini-BEHAVIOR: A Procedurally Generated Benchmark for Long-horizon Decision-Making in Embodied AI}, 176 | author={Emily Jin and Jiaheng Hu and Zhuoyi Huang and Ruohan Zhang and Jiajun Wu and Li Fei-Fei and Roberto Mart{\'i}n-Mart{\'i}n}, 177 | year={2023}, 178 | journal={arXiv preprint 2310.01824}, 179 | } 180 | ``` 181 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/__init__.py -------------------------------------------------------------------------------- /auto_control.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | from gym_minigrid.wrappers import * 5 | from mini_behavior.window import Window 6 | from mini_behavior.utils.save import get_step, save_demo 7 | from mini_behavior.grid import GridDimension 8 | import numpy as np 9 | import json 10 | 11 | # Size in pixels of a tile in the full-scale human view 12 | TILE_PIXELS = 32 13 | show_furniture = False 14 | 15 | 16 | def redraw(img): 17 | if not args.agent_view: 18 | img = env.render('rgb_array', tile_size=args.tile_size) 19 | 20 | window.no_closeup() 21 | window.set_inventory(env) 22 | window.show_img(img) 23 | 24 | 25 | def render_furniture(): 26 | global show_furniture 27 | show_furniture = not show_furniture 28 | 29 | if show_furniture: 30 | img = np.copy(env.furniture_view) 31 | 32 | # i, j = env.agent.cur_pos 33 | i, j = env.agent_pos 34 | ymin = j * TILE_PIXELS 35 | ymax = (j + 1) * TILE_PIXELS 36 | xmin = i * TILE_PIXELS 37 | xmax = (i + 1) * TILE_PIXELS 38 | 39 | img[ymin:ymax, xmin:xmax, :] = GridDimension.render_agent( 40 | img[ymin:ymax, xmin:xmax, :], env.agent_dir) 41 | img = env.render_furniture_states(img) 42 | 43 | window.show_img(img) 44 | else: 45 | obs = env.gen_obs() 46 | redraw(obs) 47 | 48 | 49 | def show_states(): 50 | imgs = env.render_states() 51 | window.show_closeup(imgs) 52 | 53 | 54 | def reset(): 55 | if args.seed != -1: 56 | env.seed(args.seed) 57 | 58 | obs = env.reset() 59 | 60 | if hasattr(env, 'mission'): 61 | print('Mission: %s' % env.mission) 62 | window.set_caption(env.mission) 63 | 64 | redraw(obs) 65 | 66 | 67 | def load(): 68 | if args.seed != -1: 69 | env.seed(args.seed) 70 | 71 | env.reset() 72 | obs = env.load_state(args.load) 73 | 74 | if hasattr(env, 'mission'): 75 | print('Mission: %s' % env.mission) 76 | window.set_caption(env.mission) 77 | 78 | redraw(obs) 79 | 80 | 81 | def step(action): 82 | prev_obs = env.gen_obs() 83 | obs, reward, done, info = env.step(action) 84 | 85 | print('step=%s, reward=%.2f' % (env.step_count, reward)) 86 | 87 | if args.save: 88 | # TODO: what is the get_step doing? 89 | # step_count, step = get_step(env) 90 | all_steps[env.step_count] = (prev_obs, action) 91 | 92 | if done: 93 | print('done!') 94 | if args.save: 95 | save_demo(all_steps, args.env, env.episode) 96 | reset() 97 | else: 98 | redraw(obs) 99 | 100 | 101 | def switch_dim(dim): 102 | env.switch_dim(dim) 103 | print(f'switching to dim: {env.render_dim}') 104 | obs = env.gen_obs() 105 | redraw(obs) 106 | 107 | 108 | def key_handler_cartesian(event): 109 | print('pressed', event.key) 110 | if event.key == 'escape': 111 | window.close() 112 | return 113 | if event.key == 'backspace': 114 | reset() 115 | return 116 | if event.key == 'left': 117 | step(env.actions.left) 118 | return 119 | if event.key == 'right': 120 | step(env.actions.right) 121 | return 122 | if event.key == 'up': 123 | step(env.actions.forward) 124 | return 125 | # Spacebar 126 | if event.key == ' ': 127 | render_furniture() 128 | return 129 | if event.key == 'pageup': 130 | step('choose') 131 | return 132 | if event.key == 'enter': 133 | env.save_state() 134 | return 135 | if event.key == 'pagedown': 136 | show_states() 137 | return 138 | if event.key == '0': 139 | switch_dim(None) 140 | return 141 | if event.key == '1': 142 | switch_dim(0) 143 | return 144 | if event.key == '2': 145 | switch_dim(1) 146 | return 147 | if event.key == '3': 148 | switch_dim(2) 149 | return 150 | 151 | # Todo: add other primitive actions 152 | def key_handler_primitive(event): 153 | print('pressed', event.key) 154 | if event.key == 'escape': 155 | window.close() 156 | return 157 | if event.key == 'left': 158 | step(env.actions.left) 159 | return 160 | if event.key == 'right': 161 | step(env.actions.right) 162 | return 163 | if event.key == 'up': 164 | step(env.actions.forward) 165 | return 166 | if event.key == '0': 167 | step(env.actions.pickup_0) 168 | return 169 | if event.key == '1': 170 | step(env.actions.pickup_1) 171 | return 172 | if event.key == '2': 173 | step(env.actions.pickup_2) 174 | return 175 | if event.key == '3': 176 | step(env.actions.drop_0) 177 | return 178 | if event.key == '4': 179 | step(env.actions.drop_1) 180 | return 181 | if event.key == '5': 182 | step(env.actions.drop_2) 183 | return 184 | if event.key == 't': 185 | step(env.actions.toggle) 186 | return 187 | if event.key == 'o': 188 | step(env.actions.open) 189 | return 190 | if event.key == 'c': 191 | step(env.actions.close) 192 | return 193 | if event.key == 'k': 194 | step(env.actions.cook) 195 | return 196 | if event.key == 's': 197 | step(env.actions.slice) 198 | return 199 | if event.key == 'i': 200 | step(env.actions.drop_in) 201 | return 202 | if event.key == 'pagedown': 203 | show_states() 204 | return 205 | 206 | 207 | parser = argparse.ArgumentParser() 208 | parser.add_argument( 209 | "--env", 210 | help="gym environment to load", 211 | # default='MiniGrid-ThrowingAwayLeftoversFour-8x8-N2-v1' 212 | # default='MiniGrid-FloorPlanEnv-16x16-N1-v0' 213 | # default='MiniGrid-TwoRoomNavigation-8x8-N2-v0' 214 | default='MiniGrid-AutoGenerate-16x16-N2-v0' 215 | # default='MiniGrid-CleaningACar-16x16-N2-v1' 216 | # default="MiniGrid-ThawingFrozenFood-16x16-N2-v0" 217 | # default="MiniGrid-ThrowingAwayLeftoversFour-8x8-N2-v1" 218 | ) 219 | parser.add_argument( 220 | "--seed", 221 | type=int, 222 | help="random seed to generate the environment with", 223 | default=-1 224 | ) 225 | parser.add_argument( 226 | "--tile_size", 227 | type=int, 228 | help="size at which to render tiles", 229 | default=32 230 | ) 231 | parser.add_argument( 232 | '--agent_view', 233 | default=False, 234 | help="draw the agent sees (partially observable view)", 235 | action='store_true' 236 | ) 237 | # NEW 238 | parser.add_argument( 239 | "--save", 240 | default=False, 241 | help="whether or not to save the demo_16" 242 | ) 243 | # NEW 244 | parser.add_argument( 245 | "--load", 246 | default=None, 247 | help="path to load state from" 248 | ) 249 | # NEW 250 | parser.add_argument( 251 | "--auto_env", 252 | default=True, 253 | help='flag to procedurally generate floorplan' 254 | ) 255 | # NEW 256 | parser.add_argument( 257 | "--auto_env_config", 258 | help='Path to auto environment JSON file', 259 | default='mini_behavior/floorplans/init_install_printer.json' 260 | ) 261 | 262 | if __name__ == '__main__': 263 | args = parser.parse_args() 264 | if args.auto_env: 265 | with open(args.auto_env_config, 'r') as f: 266 | initial_dict = json.load(f) 267 | env=gym.make(args.env, initial_dict=initial_dict) 268 | else: 269 | env = gym.make(args.env) 270 | 271 | env.teleop_mode() 272 | if args.save: 273 | # We do not support save for cartesian action space 274 | assert env.mode == "primitive" 275 | 276 | all_steps = {} 277 | 278 | if args.agent_view: 279 | env = RGBImgPartialObsWrapper(env) 280 | env = ImgObsWrapper(env) 281 | 282 | window = Window('mini_behavior - ' + args.env) 283 | if env.mode == "cartesian": 284 | window.reg_key_handler(key_handler_cartesian) 285 | elif env.mode == "primitive": 286 | window.reg_key_handler(key_handler_primitive) 287 | 288 | if args.load is None: 289 | reset() 290 | else: 291 | load() 292 | 293 | # Blocking event loop 294 | window.show(block=True) 295 | -------------------------------------------------------------------------------- /convert_scenes.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from mini_behavior.utils.scene_to_grid import gen_grid_from_img 3 | import os 4 | 5 | # run this to convert iGibson floor plan image to grid image 6 | # takes in img paths as args (default: process all imgs in scenes dir) 7 | 8 | dir_path = os.path.dirname('mini_behavior') 9 | img_dir = os.path.join(dir_path, 'mini_behavior/scenes') 10 | list_scenes = os.listdir(img_dir) 11 | grids_dir = os.path.join(dir_path, 'mini_behavior/floorplans') 12 | 13 | parser = argparse.ArgumentParser() 14 | parser.add_argument("--imgs", nargs='+', default=list_scenes, 15 | help="path of the floor plan image (REQUIRED)") 16 | 17 | args = parser.parse_args() 18 | 19 | for img in args.imgs: 20 | grid_img_path = os.path.join(grids_dir, img) 21 | 22 | if os.path.exists(grid_img_path): 23 | print('grid for {} already generated'.format(img)) 24 | else: 25 | grid = gen_grid_from_img(img=img, img_dir=img_dir, save_dir=grids_dir) 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /img/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/img/overview.png -------------------------------------------------------------------------------- /img/printer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/img/printer.gif -------------------------------------------------------------------------------- /img/visualizations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/img/visualizations.png -------------------------------------------------------------------------------- /manual_control.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | from gym_minigrid.wrappers import * 5 | from mini_behavior.window import Window 6 | from mini_behavior.utils.save import get_step, save_demo 7 | from mini_behavior.grid import GridDimension 8 | import numpy as np 9 | 10 | # Size in pixels of a tile in the full-scale human view 11 | TILE_PIXELS = 32 12 | show_furniture = False 13 | 14 | 15 | def redraw(img): 16 | if not args.agent_view: 17 | img = env.render('rgb_array', tile_size=args.tile_size) 18 | 19 | window.no_closeup() 20 | window.set_inventory(env) 21 | window.show_img(img) 22 | 23 | 24 | def render_furniture(): 25 | global show_furniture 26 | show_furniture = not show_furniture 27 | 28 | if show_furniture: 29 | img = np.copy(env.furniture_view) 30 | 31 | # i, j = env.agent.cur_pos 32 | i, j = env.agent_pos 33 | ymin = j * TILE_PIXELS 34 | ymax = (j + 1) * TILE_PIXELS 35 | xmin = i * TILE_PIXELS 36 | xmax = (i + 1) * TILE_PIXELS 37 | 38 | img[ymin:ymax, xmin:xmax, :] = GridDimension.render_agent( 39 | img[ymin:ymax, xmin:xmax, :], env.agent_dir) 40 | img = env.render_furniture_states(img) 41 | 42 | window.show_img(img) 43 | else: 44 | obs = env.gen_obs() 45 | redraw(obs) 46 | 47 | 48 | def show_states(): 49 | imgs = env.render_states() 50 | window.show_closeup(imgs) 51 | 52 | 53 | def reset(): 54 | if args.seed != -1: 55 | env.seed(args.seed) 56 | 57 | obs = env.reset() 58 | 59 | if hasattr(env, 'mission'): 60 | print('Mission: %s' % env.mission) 61 | window.set_caption(env.mission) 62 | 63 | redraw(obs) 64 | 65 | 66 | def load(): 67 | if args.seed != -1: 68 | env.seed(args.seed) 69 | 70 | env.reset() 71 | obs = env.load_state(args.load) 72 | 73 | if hasattr(env, 'mission'): 74 | print('Mission: %s' % env.mission) 75 | window.set_caption(env.mission) 76 | 77 | redraw(obs) 78 | 79 | 80 | def step(action): 81 | prev_obs = env.gen_obs() 82 | obs, reward, done, info = env.step(action) 83 | 84 | print('step=%s, reward=%.2f' % (env.step_count, reward)) 85 | 86 | if args.save: 87 | all_steps[env.step_count] = (prev_obs, action) 88 | 89 | if done: 90 | print('done!') 91 | if args.save: 92 | save_demo(all_steps, args.env, env.episode) 93 | reset() 94 | else: 95 | redraw(obs) 96 | 97 | 98 | def switch_dim(dim): 99 | env.switch_dim(dim) 100 | print(f'switching to dim: {env.render_dim}') 101 | obs = env.gen_obs() 102 | redraw(obs) 103 | 104 | 105 | def key_handler_cartesian(event): 106 | print('pressed', event.key) 107 | if event.key == 'escape': 108 | window.close() 109 | return 110 | if event.key == 'backspace': 111 | reset() 112 | return 113 | if event.key == 'left': 114 | step(env.actions.left) 115 | return 116 | if event.key == 'right': 117 | step(env.actions.right) 118 | return 119 | if event.key == 'up': 120 | step(env.actions.forward) 121 | return 122 | # Spacebar 123 | if event.key == ' ': 124 | render_furniture() 125 | return 126 | if event.key == 'pageup': 127 | step('choose') 128 | return 129 | if event.key == 'enter': 130 | env.save_state() 131 | return 132 | if event.key == 'pagedown': 133 | show_states() 134 | return 135 | if event.key == '0': 136 | switch_dim(None) 137 | return 138 | if event.key == '1': 139 | switch_dim(0) 140 | return 141 | if event.key == '2': 142 | switch_dim(1) 143 | return 144 | if event.key == '3': 145 | switch_dim(2) 146 | return 147 | 148 | def key_handler_primitive(event): 149 | print('pressed', event.key) 150 | if event.key == 'escape': 151 | window.close() 152 | return 153 | if event.key == 'left': 154 | step(env.actions.left) 155 | return 156 | if event.key == 'right': 157 | step(env.actions.right) 158 | return 159 | if event.key == 'up': 160 | step(env.actions.forward) 161 | return 162 | if event.key == '0': 163 | step(env.actions.pickup_0) 164 | return 165 | if event.key == '1': 166 | step(env.actions.pickup_1) 167 | return 168 | if event.key == '2': 169 | step(env.actions.pickup_2) 170 | return 171 | if event.key == '3': 172 | step(env.actions.drop_0) 173 | return 174 | if event.key == '4': 175 | step(env.actions.drop_1) 176 | return 177 | if event.key == '5': 178 | step(env.actions.drop_2) 179 | return 180 | if event.key == 't': 181 | step(env.actions.toggle) 182 | return 183 | if event.key == 'o': 184 | step(env.actions.open) 185 | return 186 | if event.key == 'c': 187 | step(env.actions.close) 188 | return 189 | if event.key == 'k': 190 | step(env.actions.cook) 191 | return 192 | if event.key == 's': 193 | step(env.actions.slice) 194 | return 195 | if event.key == 'i': 196 | step(env.actions.drop_in) 197 | return 198 | if event.key == 'pagedown': 199 | show_states() 200 | return 201 | 202 | 203 | parser = argparse.ArgumentParser() 204 | parser.add_argument( 205 | "--env", 206 | help="gym environment to load", 207 | default='MiniGrid-InstallingAPrinter-8x8-N2-v0' 208 | ) 209 | parser.add_argument( 210 | "--seed", 211 | type=int, 212 | help="random seed to generate the environment with", 213 | default=-1 214 | ) 215 | parser.add_argument( 216 | "--tile_size", 217 | type=int, 218 | help="size at which to render tiles", 219 | default=32 220 | ) 221 | parser.add_argument( 222 | '--agent_view', 223 | default=False, 224 | help="draw the agent sees (partially observable view)", 225 | action='store_true' 226 | ) 227 | # NEW 228 | parser.add_argument( 229 | "--save", 230 | default=False, 231 | help="whether or not to save the demo_16" 232 | ) 233 | # NEW 234 | parser.add_argument( 235 | "--load", 236 | default=None, 237 | help="path to load state from" 238 | ) 239 | 240 | args = parser.parse_args() 241 | 242 | env = gym.make(args.env) 243 | env.teleop_mode() 244 | if args.save: 245 | # We do not support save for cartesian action space 246 | assert env.mode == "primitive" 247 | 248 | all_steps = {} 249 | 250 | if args.agent_view: 251 | env = RGBImgPartialObsWrapper(env) 252 | env = ImgObsWrapper(env) 253 | 254 | window = Window('mini_behavior - ' + args.env) 255 | if env.mode == "cartesian": 256 | window.reg_key_handler(key_handler_cartesian) 257 | elif env.mode == "primitive": 258 | window.reg_key_handler(key_handler_primitive) 259 | 260 | if args.load is None: 261 | reset() 262 | else: 263 | load() 264 | 265 | # Blocking event loop 266 | window.show(block=True) 267 | -------------------------------------------------------------------------------- /mini_bddl/__init__.py: -------------------------------------------------------------------------------- 1 | from .actions import * 2 | from .objs import * 3 | from .states import * 4 | -------------------------------------------------------------------------------- /mini_bddl/actions.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.actions import * 2 | 3 | ALL_ACTIONS = ['pickup', 'drop', 'drop_in', 'drop_on', 'drop_under', 'toggle', 'open', 'close', 'slice', 'cook'] 4 | DEFAULT_ACTIONS = [] 5 | 6 | ACTION_FUNC_MAPPING = { 7 | 'pickup': Pickup, 8 | 'drop': Drop, 9 | 'drop_in': DropIn, 10 | 'toggle': Toggle, 11 | 'open': Open, 12 | 'close': Close, 13 | 'slice': Slice, 14 | 'cook': Cook 15 | } 16 | 17 | CONTROLS = ['left', 'right', 'forward'] # 'down' 18 | 19 | -------------------------------------------------------------------------------- /mini_bddl/objs.py: -------------------------------------------------------------------------------- 1 | OBJECTS = [ 2 | "apple", "ashcan", 3 | "backpack", "ball", "banana", "basket", "bed", "beef", "bin", "blender", "book", "bow", "box", "bread", "broom", "bucket", 4 | "cabinet", "cake", "calculator", "candle", "candy", "car", "carton", "carving_knife", "casserole", "chicken", "chip", "cookie", "countertop", 5 | "date", "dustpan", # door 6 | "egg", "electric_refrigerator", 7 | "fish", "folder", "fork", # "floor", 8 | "gym_shoe", 9 | "hamburger", "hammer", "hardback", 10 | "jar", "jewelry", "juice", 11 | "kettle", "knife", 12 | "lemon", "lettuce", 13 | "necklace", "notebook", 14 | "olive", 15 | "package", "pan", "pen", "pencil", "plate", "plywood", "pop", "printer", 16 | "radish", "rag", 17 | "salad", "sandwich", "saw", "scrub_brush", "shelf", "shoe", "shower", "sink", "soap", "sock", "sofa", "soup", "spoon", "stove", "strawberry", 18 | "table", "tea_bag", "teapot", "toilet", "tomato", "towel", 19 | "vegetable_oil", 20 | "water", "window", 21 | "pot_plant", "marker", "chair", "document", "oatmeal", "sugar" 22 | ] 23 | 24 | FURNITURE = ['ashcan', 'bed', 'bin', 'box', 'bucket', 'cabinet', 'chair', 'car', 'countertop', 'electric_refrigerator', 'shelf', 'shower', 'sink', 'sofa', 'stove', 'table', 'window'] 25 | # Map of object type to integers 26 | OBJECT_TO_IDX = { 27 | 'unseen': 0, 28 | 'empty': 1, 29 | "apple": 2, 30 | "ashcan": 3, 31 | "backpack": 4, 32 | "ball": 5, 33 | "banana": 6, 34 | "basket": 7, 35 | "bed": 8, 36 | "beef": 9, 37 | "bin": 10, 38 | "blender": 11, 39 | "book": 12, 40 | "bow": 13, 41 | "bread": 14, 42 | "broom": 15, 43 | "bucket": 16, 44 | "cabinet": 17, 45 | "cake": 18, 46 | "calculator": 19, 47 | "candy": 20, 48 | "car": 21, 49 | "carton": 22, 50 | "carving_knife": 23, 51 | "casserole": 24, 52 | "chicken": 25, 53 | "chip": 26, 54 | "cookie": 27, 55 | "countertop": 28, 56 | "date": 29, 57 | "door": 30, 58 | "dustpan": 31, 59 | "egg": 32, 60 | "electric_refrigerator": 33, 61 | "fish": 34, 62 | "floor": 35, 63 | "folder": 36, 64 | "fork": 37, 65 | "gym_shoe": 38, 66 | "hamburger": 39, 67 | "hammer": 40, 68 | "highlighter": 41, 69 | "jar": 42, 70 | "jewelry": 43, 71 | "juice": 44, 72 | "kettle": 45, 73 | "knife": 46, 74 | "lemon": 47, 75 | "lettuce": 48, 76 | "necklace": 49, 77 | "notebook": 50, 78 | "olive": 51, 79 | "package": 52, 80 | "pan": 53, 81 | "pen": 54, 82 | "pencil": 55, 83 | "plate": 56, 84 | "plywood": 57, 85 | "pop": 58, 86 | "printer": 59, 87 | "radish": 60, 88 | "rag": 61, 89 | "salad": 62, 90 | "sandwich": 63, 91 | "saw": 64, 92 | "scrub_brush": 65, 93 | "shelf": 66, 94 | "shoe": 67, 95 | "shower": 68, 96 | "sink": 69, 97 | "soap": 70, 98 | "sock": 71, 99 | "sofa": 72, 100 | "soup": 73, 101 | "spoon": 74, 102 | "stove": 75, 103 | "strawberry": 76, 104 | "table": 77, 105 | "tea_bag": 78, 106 | "teapot": 79, 107 | "toilet": 80, 108 | "tomato": 81, 109 | "towel": 82, 110 | "vegetable_oil": 83, 111 | "wall": 84, 112 | "water": 85, 113 | "window": 86, 114 | "pot_plant": 87, 115 | "marker": 88, 116 | "chair": 89, 117 | "document": 90, 118 | "oatmeal": 91, 119 | "sugar": 92, 120 | "candle": 93, 121 | "box": 94, 122 | "hardback": 95, 123 | "goal": 96, 124 | "agent": 97 125 | } 126 | 127 | IDX_TO_OBJECT = dict(zip(OBJECT_TO_IDX.values(), OBJECT_TO_IDX.keys())) 128 | 129 | 130 | OBJECT_TO_STR = { 131 | "apple": "A", 132 | "ashcan": "A", 133 | "backpack": "B", 134 | "ball": "B", 135 | "banana": "B", 136 | "basket": "B", 137 | "bed": "B", 138 | "beef": "B", 139 | "bin": "B", 140 | "blender": "B", 141 | "book": "B", 142 | "bow": "B", 143 | "bread": "B", 144 | "broom": "B", 145 | "bucket": "B", 146 | "cabinet": "C", 147 | "cake": "C", 148 | "calculator": "C", 149 | "candy": "C", 150 | "car": "C", 151 | "carton": "C", 152 | "carving_knife": "C", 153 | "casserole": "C", 154 | "chicken": "C", 155 | "chip": "C", 156 | "cookie": "C", 157 | "countertop": "C", 158 | "date": "D", 159 | "door": "D", 160 | "dustpan": "D", 161 | "egg": "E", 162 | "electric_refrigerator": "E", 163 | "fish": "F", 164 | "floor": "F", 165 | "folder": "F", 166 | "fork": "F", 167 | "gym_shoe": "G", 168 | "hamburger": "H", 169 | "hammer": "H", 170 | "highlighter": "H", 171 | "jar": "J", 172 | "jewelry": "J", 173 | "juice": "J", 174 | "kettle": "K", 175 | "knife": "K", 176 | "lemon": "L", 177 | "lettuce": "L", 178 | "necklace": "N", 179 | "notebook": "N", 180 | "olive": "O", 181 | "package": "P", 182 | "pan": "P", 183 | "pen": "P", 184 | "pencil": "P", 185 | "plate": "P", 186 | "plywood": "P", 187 | "pop": "P", 188 | "printer": "P", 189 | "radish": "R", 190 | "rag": "R", 191 | "salad": "S", 192 | "sandwich": "S", 193 | "saw": "S", 194 | "scrub_brush": "S", 195 | "shelf": "S", 196 | "shoe": "S", 197 | "shower": "S", 198 | "sink": "S", 199 | "soap": "S", 200 | "sock": "S", 201 | "sofa": "S", 202 | "soup": "S", 203 | "spoon": "S", 204 | "stove": "S", 205 | "strawberry": "S", 206 | "table": "T", 207 | "tea_bag": "T", 208 | "teapot": "T", 209 | "toilet": "T", 210 | "tomato": "T", 211 | "towel": "T", 212 | "vegetable_oil": "V", 213 | "wall": "W", 214 | "water": "W", 215 | "window ": "W", 216 | "pot_plant": "P", 217 | "marker": "M", 218 | "chair": "C", 219 | "oatmeal": "O", 220 | "sugar": "S", 221 | "box": "B", 222 | "hardback": "H", 223 | "candle": "C" 224 | } 225 | 226 | FURNITURE_CANNOT_ON = ['ashcan', 'bed', 'bin', 'chair', 'shower', 'car', 'sink', 'window'] 227 | -------------------------------------------------------------------------------- /mini_bddl/states.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.states import * 2 | 3 | ALL_STATES = [ 4 | 'atsamelocation', 5 | 'cleaningTool', 6 | 'coldSource', 7 | 'cookable', 8 | 'dustyable', 9 | 'freezable', 10 | 'heatSource', 11 | 'infovofrobot', 12 | 'inhandofrobot', 13 | 'inreachofrobot', 14 | 'insameroomasrobot', 15 | 'inside', 16 | 'nextto', 17 | 'onfloor', 18 | 'onTop', 19 | 'openable', 20 | 'sliceable', 21 | 'slicer', 22 | 'soakable', 23 | 'stainable', 24 | 'toggleable', 25 | 'under' 26 | 'waterSource' 27 | # 'touching', TODO: uncomment once implemented 28 | ] 29 | 30 | # Touching 31 | # ObjectsInFOVOfRobot, 32 | 33 | DEFAULT_STATES = [ 34 | 'atsamelocation', 35 | 'infovofrobot', 36 | 'inhandofrobot', 37 | 'inreachofrobot', 38 | 'insameroomasrobot', 39 | 'inside', 40 | 'nextto', 41 | 'onfloor', 42 | 'onTop', 43 | 'under' 44 | ] 45 | 46 | 47 | ABILITIES = [ 48 | 'cookable', 49 | 'dustyable', 50 | 'freezable', 51 | 'openable', 52 | 'sliceable', 53 | 'soakable', 54 | 'stainable', 55 | 'toggleable', 56 | ] 57 | 58 | FURNATURE_STATES = [ 59 | 'dustyable', 60 | 'openable', 61 | 'stainable', 62 | 'toggleable', 63 | ] 64 | 65 | # state (str) to state (function) mapping 66 | STATE_FUNC_MAPPING = { 67 | 'atsamelocation': AtSameLocation, 68 | 'cleaningTool': CleaningTool, 69 | 'coldSource': HeatSourceOrSink, 70 | 'cookable': Cooked, 71 | 'dustyable': Dusty, 72 | 'freezable': Frozen, 73 | 'heatSource': HeatSourceOrSink, 74 | 'infovofrobot': InFOVOfRobot, 75 | 'inhandofrobot': InHandOfRobot, 76 | 'inreachofrobot': InReachOfRobot, 77 | 'insameroomasrobot': InSameRoomAsRobot, 78 | 'inside': Inside, 79 | 'nextto': NextTo, 80 | 'onfloor': OnFloor, 81 | 'onTop': OnTop, 82 | 'openable': Opened, 83 | 'sliceable': Sliced, 84 | 'slicer': Slicer, 85 | 'soakable': Soaked, 86 | 'stainable': Stained, 87 | 'toggleable': ToggledOn, 88 | 'under': Under, 89 | 'waterSource': WaterSource 90 | # 'touching', TODO: uncomment once implemented 91 | } 92 | 93 | 94 | ######################################################################################################################## 95 | 96 | # FROM BDDL 97 | 98 | # TEXTURE_CHANGE_PRIORITY = { 99 | # Frozen: 4, 100 | # Burnt: seed 10_3, 101 | # Cooked: seed 0_2, 102 | # Soaked: seed 0_2, 103 | # ToggledOn: 0, 104 | # } 105 | 106 | -------------------------------------------------------------------------------- /mini_behavior/__init__.py: -------------------------------------------------------------------------------- 1 | ## FROM MINIGRID REPO 2 | 3 | # Import the envs module so that envs register themselves 4 | import mini_behavior.envs 5 | 6 | # Import wrappers so it's accessible when installing with pip 7 | import gym_minigrid.wrappers 8 | -------------------------------------------------------------------------------- /mini_behavior/envs/__init__.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.envs.boxing_books_up_for_storage import * 2 | from mini_behavior.envs.cleaning_a_car import * 3 | from mini_behavior.envs.cleaning_shoes import * 4 | from mini_behavior.envs.cleaning_up_the_kitchen_only import * 5 | from mini_behavior.envs.collect_misplaced_items import * 6 | from mini_behavior.envs.installing_a_printer import * 7 | from mini_behavior.envs.laying_wood_floors import * 8 | from mini_behavior.envs.making_tea import * 9 | from mini_behavior.envs.moving_boxes_to_storage import * 10 | from mini_behavior.envs.opening_packages import * 11 | from mini_behavior.envs.organizing_file_cabinet import * 12 | from mini_behavior.envs.preparing_salad import * 13 | from mini_behavior.envs.putting_away_dishes_after_cleaning import * 14 | from mini_behavior.envs.setting_up_candles import * 15 | from mini_behavior.envs.sorting_books import * 16 | from mini_behavior.envs.storing_food import * 17 | from mini_behavior.envs.thawing_frozen_food import * 18 | from mini_behavior.envs.throwing_away_leftovers import * 19 | from mini_behavior.envs.transition import * 20 | from mini_behavior.envs.washing_pots_and_pans import * 21 | from mini_behavior.envs.watering_houseplants import * 22 | 23 | from mini_behavior.envs.navigation import * 24 | from mini_behavior.envs.throwleftovers_floorplan import * 25 | from mini_behavior.envs.two_room_nav import * 26 | 27 | # extra 28 | from mini_behavior.envs.preparing_salad_floorplan import * 29 | from mini_behavior.envs.auto_env import * -------------------------------------------------------------------------------- /mini_behavior/envs/boxing_books_up_for_storage.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class BoxingBooksUpForStorageEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to clean a car 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | ): 18 | num_objs = {'book': 7, 'shelf': 1, 'box': 1} 19 | 20 | self.mission = 'box up books for storage' 21 | 22 | super().__init__(mode=mode, 23 | num_objs=num_objs, 24 | room_size=room_size, 25 | num_rows=num_rows, 26 | num_cols=num_cols, 27 | max_steps=max_steps 28 | ) 29 | 30 | box = self.objs['box'][0] 31 | box.width = 3 32 | box.height = 3 33 | 34 | def _gen_objs(self): 35 | book = self.objs['book'] 36 | shelf = self.objs['shelf'][0] 37 | box = self.objs['box'][0] 38 | 39 | self.place_obj(shelf) 40 | self.place_obj(box) 41 | 42 | for obj in book[:5]: 43 | self.place_obj(obj) 44 | 45 | shelf_pos = self._rand_subset(shelf.all_pos, 2) 46 | self.put_obj(book[5], *shelf_pos[0], 2) 47 | self.put_obj(book[6], *shelf_pos[1], 2) 48 | 49 | 50 | 51 | def _end_conditions(self): 52 | book = self.objs['book'] 53 | box = self.objs['box'][0] 54 | 55 | for obj in book: 56 | if not obj.check_rel_state(self, box, 'inside'): 57 | return False 58 | 59 | return True 60 | 61 | 62 | # non human input env 63 | register( 64 | id='MiniGrid-BoxingBooksUpForStorage-16x16-N2-v0', 65 | entry_point='mini_behavior.envs:BoxingBooksUpForStorageEnv' 66 | ) 67 | 68 | # human input env 69 | register( 70 | id='MiniGrid-BoxingBooksUpForStorage-16x16-N2-v1', 71 | entry_point='mini_behavior.envs:BoxingBooksUpForStorageEnv', 72 | kwargs={'mode': 'cartesian'} 73 | ) 74 | -------------------------------------------------------------------------------- /mini_behavior/envs/cleaning_a_car.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class CleaningACarEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to clean a car 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | ): 18 | num_objs = {'car': 1, 'rag': 1, 'shelf': 1, 'soap': 1, 'bucket': 1, 'sink': 1} 19 | 20 | self.mission = 'clean a car' 21 | 22 | super().__init__(mode=mode, 23 | num_objs=num_objs, 24 | room_size=room_size, 25 | num_rows=num_rows, 26 | num_cols=num_cols, 27 | max_steps=max_steps 28 | ) 29 | 30 | def _gen_objs(self): 31 | car = self.objs['car'][0] 32 | rag = self.objs['rag'][0] 33 | shelf = self.objs['shelf'][0] 34 | soap = self.objs['soap'][0] 35 | bucket = self.objs['bucket'][0] 36 | sink = self.objs['sink'][0] 37 | 38 | self.place_obj(shelf) 39 | self.place_obj(car) 40 | self.place_obj(bucket) 41 | self.place_obj(sink) 42 | 43 | # place rag and soap on shelf 44 | rag_pos, soap_pos = self._rand_subset(shelf.all_pos, 2) 45 | self.put_obj(rag, *rag_pos, 2) 46 | self.put_obj(soap, *soap_pos, 2) 47 | 48 | # rag not soaked 49 | rag.states['soakable'].set_value(False) 50 | 51 | # dusty car 52 | car.states['dustyable'].set_value(True) 53 | 54 | def _init_conditions(self): 55 | for obj_type in ['car', 'rag', 'shelf', 'soap', 'bucket', 'sink']: 56 | assert obj_type in self.objs.keys(), f"No {obj_type}" 57 | 58 | car = self.objs['car'][0] 59 | rag = self.objs['rag'][0] 60 | shelf = self.objs['shelf'][0] 61 | soap = self.objs['soap'][0] 62 | bucket = self.objs['bucket'][0] 63 | 64 | assert car.check_abs_state(self, 'onfloor') 65 | assert rag.check_rel_state(self, shelf, 'onTop') 66 | assert not rag.check_abs_state(self, 'soakable') 67 | assert soap.check_rel_state(self, soap, 'onTop') 68 | assert car.check_abs_state(self, 'dustyable') 69 | assert bucket.check_abs_state(self, 'onfloor') 70 | 71 | return True 72 | 73 | 74 | 75 | def _end_conditions(self): 76 | car = self.objs['car'][0] 77 | rag = self.objs['rag'][0] 78 | soap = self.objs['soap'][0] 79 | bucket = self.objs['bucket'][0] 80 | 81 | if not car.check_abs_state(self, 'dustyable') and soap.check_rel_state(self, bucket, 'inside') and rag.check_rel_state(self, bucket, 'inside'): 82 | return True 83 | else: 84 | return False 85 | 86 | 87 | # non human input env 88 | register( 89 | id='MiniGrid-CleaningACar-16x16-N2-v0', 90 | entry_point='mini_behavior.envs:CleaningACarEnv' 91 | ) 92 | 93 | # human input env 94 | register( 95 | id='MiniGrid-CleaningACar-16x16-N2-v1', 96 | entry_point='mini_behavior.envs:CleaningACarEnv', 97 | kwargs={'mode': 'cartesian'} 98 | ) 99 | -------------------------------------------------------------------------------- /mini_behavior/envs/cleaning_shoes.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class CleaningShoesEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to clean a car 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=8, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | ): 18 | num_objs = {'soap': 1, 'bed': 1, 'rag': 1, 'towel': 1, 'shoe': 4, 'sink': 1} 19 | 20 | self.mission = 'clean shoes' 21 | 22 | super().__init__(mode=mode, 23 | num_objs=num_objs, 24 | room_size=room_size, 25 | num_rows=num_rows, 26 | num_cols=num_cols, 27 | max_steps=max_steps 28 | ) 29 | 30 | def _gen_objs(self): 31 | bed = self.objs['bed'][0] 32 | soap = self.objs['soap'][0] 33 | rag = self.objs['rag'][0] 34 | towel = self.objs['towel'][0] 35 | sink = self.objs['sink'][0] 36 | 37 | shoes = self.objs['shoe'] 38 | 39 | self.place_obj(bed) 40 | self.place_obj(towel) 41 | self.place_obj(sink) 42 | 43 | # place rag, soap, shoes on bed 44 | rag_pos, soap_pos, shoe_0, shoe_1, shoe_2, shoe_3 = self._rand_subset(bed.all_pos, 6) 45 | self.put_obj(rag, *rag_pos, 1) 46 | self.put_obj(soap, *soap_pos, 1) 47 | self.put_obj(shoes[0], *shoe_0, 1) 48 | self.put_obj(shoes[1], *shoe_1, 1) 49 | self.put_obj(shoes[2], *shoe_2, 1) 50 | self.put_obj(shoes[3], *shoe_3, 1) 51 | 52 | # stain 2 shoes 53 | for shoe in shoes[:2]: 54 | shoe.states['stainable'].set_value(True) 55 | # dusty 2 shoes 56 | for shoe in shoes[2:]: 57 | shoe.states['dustyable'].set_value(True) 58 | 59 | # not soaked rag 60 | rag.states['soakable'].set_value(False) 61 | 62 | def _init_conditions(self): 63 | for obj_type in ['soap', 'bed', 'rag', 'towel', 'shoe', 'sink']: 64 | assert obj_type in self.objs.keys(), f"No {obj_type}" 65 | 66 | bed = self.objs['bed'][0] 67 | soap = self.objs['soap'][0] 68 | rag = self.objs['rag'][0] 69 | towel = self.objs['towel'][0] 70 | shoes = self.objs['shoe'] 71 | 72 | assert soap.check_rel_state(self, bed, 'onTop') 73 | assert rag.check_rel_state(self, bed, 'onTop') 74 | assert towel.check_abs_state(self, 'onfloor') 75 | 76 | for shoe in shoes: 77 | assert shoe.check_rel_state(self, bed, 'onTop') 78 | 79 | for shoe in shoes[:2]: 80 | assert shoe.check_abs_state(self, 'stainable') 81 | for shoe in shoes[2:]: 82 | assert shoe.check_abs_state(self, 'dustyable') 83 | 84 | assert not rag.check_abs_state(self, 'soakable') 85 | 86 | return True 87 | 88 | 89 | 90 | def _end_conditions(self): 91 | shoes = self.objs['shoe'] 92 | towel = self.objs['towel'][0] 93 | 94 | for shoe in shoes: 95 | if shoe.check_abs_state(self, 'stainable') or shoe.check_abs_state(self, 'dustyable'): 96 | return False 97 | 98 | return towel.check_abs_state(self, 'onfloor') 99 | 100 | 101 | # non human input env 102 | register( 103 | id='MiniGrid-CleaningShoes-16x16-N2-v0', 104 | entry_point='mini_behavior.envs:CleaningShoesEnv' 105 | ) 106 | 107 | # human input env 108 | register( 109 | id='MiniGrid-CleaningShoes-16x16-N2-v1', 110 | entry_point='mini_behavior.envs:CleaningShoesEnv', 111 | kwargs={'mode': 'cartesian'} 112 | ) 113 | -------------------------------------------------------------------------------- /mini_behavior/envs/cleaning_up_the_kitchen_only.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class CleaningUpTheKitchenOnlyEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to clean a car 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | ): 18 | num_objs = {'bin': 1, 'soap': 1, 'cabinet': 2, 'electric_refrigerator': 1, 'rag': 1, 'dustpan': 1, 19 | 'broom': 1, 'blender': 1, 'sink': 1, 'casserole': 1, 'plate': 1, 'vegetable_oil': 1, 20 | 'apple': 1, 'countertop': 1} # 'window': 1, 21 | 22 | self.mission = 'clean up the kitchen' 23 | 24 | super().__init__(mode=mode, 25 | num_objs=num_objs, 26 | room_size=room_size, 27 | num_rows=num_rows, 28 | num_cols=num_cols, 29 | max_steps=max_steps 30 | ) 31 | 32 | def _gen_objs(self): 33 | cabinets = self.objs['cabinet'] 34 | electric_refrigerator = self.objs['electric_refrigerator'][0] 35 | sink = self.objs['sink'][0] 36 | countertop = self.objs['countertop'][0] 37 | bin = self.objs['bin'][0] 38 | 39 | soap = self.objs['soap'][0] 40 | rag = self.objs['rag'][0] 41 | broom = self.objs['broom'][0] 42 | dustpan = self.objs['dustpan'][0] 43 | blender = self.objs['blender'][0] 44 | casserole = self.objs['casserole'][0] 45 | plate = self.objs['plate'][0] 46 | vegetable_oil = self.objs['vegetable_oil'][0] 47 | apple = self.objs['apple'][0] 48 | 49 | self.place_obj(cabinets[0]) 50 | self.place_obj(cabinets[1]) 51 | self.place_obj(electric_refrigerator) 52 | self.place_obj(bin) 53 | self.place_obj(sink) 54 | self.place_obj(countertop) 55 | 56 | cabinet_pos = self._rand_subset(cabinets[0].all_pos, 3) 57 | self.put_obj(soap, *cabinet_pos[0], 1) 58 | self.put_obj(rag, *cabinet_pos[1], 1) 59 | rag.states['soakable'].set_value(False) 60 | self.put_obj(dustpan, *cabinet_pos[2], 1) 61 | dustpan.states['dustyable'].set_value(True) 62 | 63 | for obj in [soap, rag, dustpan]: 64 | obj.states['inside'].set_value(cabinets[0], True) 65 | 66 | self.place_obj(broom) 67 | broom.states['dustyable'].set_value(True) 68 | self.place_obj(blender) 69 | blender.states['stainable'].set_value(True) 70 | 71 | fridge_pos = self._rand_subset(electric_refrigerator.all_pos, 4) 72 | self.put_obj(casserole, *fridge_pos[0], 1) 73 | self.put_obj(plate, *fridge_pos[1], 1) 74 | plate.states['stainable'].set_value(True) 75 | self.put_obj(vegetable_oil, *fridge_pos[2], 1) 76 | self.put_obj(apple, *fridge_pos[3], 1) 77 | 78 | for obj in [casserole, plate, vegetable_oil, apple]: 79 | obj.states['inside'].set_value(electric_refrigerator, True) 80 | 81 | # (dusty floor.n.01_1) 82 | cabinets[0].states['dustyable'].set_value(True) 83 | cabinets[1].states['dustyable'].set_value(True) 84 | 85 | def _init_conditions(self): 86 | for obj_type in ['bin', 'soap', 'cabinet', 'electric_refrigerator', 'rag', 'dustpan', 'broom', 'blender', 87 | 'sink', 'casserole', 'plate', 'vegetable_oil', 'apple', 'countertop']: 88 | assert obj_type in self.objs.keys(), f"No {obj_type}" 89 | 90 | return True 91 | 92 | 93 | 94 | def _end_conditions(self): 95 | cabinets = self.objs['cabinet'] 96 | electric_refrigerator = self.objs['electric_refrigerator'][0] 97 | sink = self.objs['sink'][0] 98 | countertop = self.objs['countertop'][0] 99 | 100 | soap = self.objs['soap'][0] 101 | rag = self.objs['rag'][0] 102 | blender = self.objs['blender'][0] 103 | casserole = self.objs['casserole'][0] 104 | plate = self.objs['plate'][0] 105 | vegetable_oil = self.objs['vegetable_oil'][0] 106 | apple = self.objs['apple'][0] 107 | 108 | if not blender.check_rel_state(self, countertop, 'onTop'): 109 | return False 110 | 111 | if not soap.check_rel_state(self, sink, 'nextto'): 112 | return False 113 | 114 | exists = False 115 | for cabinet in cabinets: 116 | if vegetable_oil.check_rel_state(self, cabinet, 'inside') and not plate.check_rel_state(self, cabinet, 'inside'): 117 | exists = True 118 | break 119 | 120 | if not exists: 121 | return False 122 | 123 | for cabinet in cabinets: 124 | if not vegetable_oil.check_rel_state(self, cabinet, 'inside') and plate.check_rel_state(self, cabinet, 'inside'): 125 | exists = True 126 | break 127 | 128 | if not exists: 129 | return False 130 | 131 | for cabinet in cabinets: 132 | if cabinet.check_abs_state(self, 'dustyable'): 133 | return False 134 | 135 | if plate.check_abs_state(self, 'stainable'): 136 | return False 137 | 138 | if not rag.check_rel_state(self, sink, 'inside') and not rag.check_rel_state(self, sink, 'nextto'): 139 | return False 140 | 141 | if not casserole.check_rel_state(self, electric_refrigerator, 'inside') or not apple.check_rel_state(self, electric_refrigerator, 'inside'): 142 | return False 143 | 144 | return True 145 | 146 | 147 | # non human input env 148 | register( 149 | id='MiniGrid-CleaningUpTheKitchenOnly-16x16-N2-v0', 150 | entry_point='mini_behavior.envs:CleaningUpTheKitchenOnlyEnv' 151 | ) 152 | 153 | # human input env 154 | register( 155 | id='MiniGrid-CleaningUpTheKitchenOnly-16x16-N2-v1', 156 | entry_point='mini_behavior.envs:CleaningUpTheKitchenOnlyEnv', 157 | kwargs={'mode': 'cartesian'} 158 | ) 159 | -------------------------------------------------------------------------------- /mini_behavior/envs/collect_misplaced_items.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class CollectMisplacedItemsEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to clean a car 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | ): 18 | num_objs = {'gym_shoe': 1, 'necklace': 1, 'notebook': 1, 'sock': 2, 'table': 2, 'cabinet': 1, 'sofa': 1} 19 | 20 | self.mission = 'collect misplaced items onto a table' 21 | 22 | super().__init__(mode=mode, 23 | num_objs=num_objs, 24 | room_size=room_size, 25 | num_rows=num_rows, 26 | num_cols=num_cols, 27 | max_steps=max_steps 28 | ) 29 | 30 | def _gen_objs(self): 31 | gym_shoe = self.objs['gym_shoe'][0] 32 | necklace = self.objs['necklace'][0] 33 | notebook = self.objs['notebook'][0] 34 | cabinet = self.objs['cabinet'][0] 35 | sofa = self.objs['sofa'][0] 36 | 37 | socks = self.objs['sock'] 38 | tables = self.objs['table'] 39 | 40 | self.place_obj(tables[0]) 41 | self.place_obj(tables[1]) 42 | self.place_obj(necklace) 43 | self.place_obj(cabinet) 44 | 45 | table_0_pos = self._rand_subset(tables[0].all_pos, 1)[0] 46 | self.put_obj(gym_shoe, *table_0_pos, 0) 47 | 48 | cabinet_pos = self._rand_subset(cabinet.all_pos, 1)[0] 49 | self.put_obj(gym_shoe, *cabinet_pos, 2) 50 | 51 | table_1_pos = self._rand_subset(tables[1].all_pos, 2)[0] 52 | self.put_obj(notebook, *table_1_pos, 0) 53 | 54 | self.place_obj(sofa) 55 | self.put_obj(socks[0], *self._rand_elem(sofa.all_pos), 1) 56 | self.place_obj(socks[1]) 57 | 58 | def _init_conditions(self): 59 | for obj_type in ['gym_shoe', 'necklace', 'notebook', 'sock', 'table', 'cabinet', 'sofa']: 60 | assert obj_type in self.objs.keys(), f"No {obj_type}" 61 | 62 | return True 63 | 64 | 65 | 66 | def _end_conditions(self): 67 | gym_shoe = self.objs['gym_shoe'] 68 | necklace = self.objs['necklace'] 69 | notebook = self.objs['notebook'] 70 | 71 | socks = self.objs['sock'] 72 | tables = self.objs['table'] 73 | 74 | for obj in gym_shoe + necklace + notebook + socks: 75 | if not obj.check_rel_state(self, tables[1], 'onTop'): 76 | return False 77 | 78 | return True 79 | 80 | 81 | # non human input env 82 | register( 83 | id='MiniGrid-CollectMisplacedItems-16x16-N2-v0', 84 | entry_point='mini_behavior.envs:CollectMisplacedItemsEnv' 85 | ) 86 | 87 | # human input env 88 | register( 89 | id='MiniGrid-CollectMisplacedItems-16x16-N2-v1', 90 | entry_point='mini_behavior.envs:CollectMisplacedItemsEnv', 91 | kwargs={'mode': 'cartesian'} 92 | ) 93 | -------------------------------------------------------------------------------- /mini_behavior/envs/installing_a_printer.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | from enum import IntEnum 4 | from gym import spaces 5 | 6 | 7 | class InstallingAPrinterEnv(RoomGrid): 8 | """ 9 | Environment in which the agent is instructed to install a printer 10 | """ 11 | 12 | def __init__( 13 | self, 14 | mode='primitive', 15 | room_size=16, 16 | num_rows=1, 17 | num_cols=1, 18 | max_steps=1e5, 19 | ): 20 | num_objs = {'printer': 1, 'table': 1} 21 | 22 | self.mission = 'install a printer' 23 | 24 | super().__init__(mode=mode, 25 | num_objs=num_objs, 26 | room_size=room_size, 27 | num_rows=num_rows, 28 | num_cols=num_cols, 29 | max_steps=max_steps 30 | ) 31 | 32 | self.actions = InstallingAPrinterEnv.Actions 33 | self.action_space = spaces.Discrete(len(self.actions)) 34 | 35 | def _gen_objs(self): 36 | printer = self.objs['printer'][0] 37 | table = self.objs['table'][0] 38 | 39 | self.place_obj(table) 40 | self.place_obj(printer) 41 | 42 | def _init_conditions(self): 43 | for obj_type in ['printer', 'table']: 44 | assert obj_type in self.objs.keys(), f"No {obj_type}" 45 | 46 | printer = self.objs['printer'][0] 47 | 48 | assert printer.check_abs_state(self, 'onfloor') 49 | assert not printer.check_abs_state(self, 'toggleable') 50 | 51 | return True 52 | 53 | def _end_conditions(self): 54 | printer = self.objs['printer'][0] 55 | table = self.objs['table'][0] 56 | 57 | if printer.check_rel_state(self, table, 'onTop') and printer.check_abs_state(self, 'toggleable'): 58 | return True 59 | else: 60 | return False 61 | 62 | 63 | register( 64 | id='MiniGrid-InstallingAPrinter-16x16-N2-v0', 65 | entry_point='mini_behavior.envs:InstallingAPrinterEnv' 66 | ) 67 | 68 | register( 69 | id='MiniGrid-InstallingAPrinter-8x8-N2-v0', 70 | entry_point='mini_behavior.envs:InstallingAPrinterEnv', 71 | kwargs={"room_size": 8, "max_steps": 1000} 72 | ) 73 | 74 | register( 75 | id='MiniGrid-InstallingAPrinter-6x6-N2-v0', 76 | entry_point='mini_behavior.envs:InstallingAPrinterEnv', 77 | kwargs={"room_size": 6, "max_steps": 1000} 78 | ) 79 | 80 | register( 81 | id='MiniGrid-InstallingAPrinter-16x16-N2-v1', 82 | entry_point='mini_behavior.envs:InstallingAPrinterEnv', 83 | kwargs={'mode': 'cartesian'} 84 | ) 85 | -------------------------------------------------------------------------------- /mini_behavior/envs/laying_wood_floors.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class LayingWoodFloorsEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to install a printer 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | ): 18 | num_objs = {'plywood': 4, 'hammer': 1, 'saw': 1} 19 | 20 | self.mission = 'laying wood floors' 21 | 22 | super().__init__(mode=mode, 23 | num_objs=num_objs, 24 | room_size=room_size, 25 | num_rows=num_rows, 26 | num_cols=num_cols, 27 | max_steps=max_steps 28 | ) 29 | 30 | def _gen_objs(self): 31 | for obj in self.obj_instances.values(): 32 | self.place_obj(obj) 33 | 34 | 35 | def _init_conditions(self): 36 | for obj_type in ['plywood', 'hammer', 'saw']: 37 | assert obj_type in self.objs.keys(), f"No {obj_type}" 38 | 39 | return True 40 | 41 | 42 | 43 | def _end_conditions(self): 44 | plywood = self.objs['plywood'] 45 | hammer = self.objs['hammer'][0] 46 | saw = self.objs['saw'][0] 47 | 48 | for wood in plywood: 49 | if not wood.check_abs_state(self, 'onfloor'): 50 | return False 51 | 52 | for wood in plywood: 53 | nextto = False 54 | for other_wood in plywood: 55 | if wood.check_rel_state(self, other_wood, 'nextto'): 56 | nextto = True 57 | 58 | if not nextto: 59 | return False 60 | 61 | return True 62 | 63 | 64 | 65 | # non human input env 66 | register( 67 | id='MiniGrid-LayingWoodFloors-16x16-N2-v0', 68 | entry_point='mini_behavior.envs:LayingWoodFloorsEnv' 69 | ) 70 | 71 | # human input env 72 | register( 73 | id='MiniGrid-LayingWoodFloors-16x16-N2-v1', 74 | entry_point='mini_behavior.envs:LayingWoodFloorsEnv', 75 | kwargs={'mode': 'cartesian'} 76 | ) 77 | -------------------------------------------------------------------------------- /mini_behavior/envs/making_tea.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class MakingTeaEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to clean a car 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | ): 18 | num_objs = {'teapot': 1, 'tea_bag': 1, 'lemon': 1, 'knife': 1, 'cabinet': 1, 'electric_refrigerator': 1, 'stove': 1} 19 | 20 | self.mission = 'make tea' 21 | 22 | super().__init__(mode=mode, 23 | num_objs=num_objs, 24 | room_size=room_size, 25 | num_rows=num_rows, 26 | num_cols=num_cols, 27 | max_steps=max_steps 28 | ) 29 | 30 | def _gen_objs(self): 31 | teapot = self.objs['teapot'][0] 32 | tea_bag = self.objs['tea_bag'][0] 33 | lemon = self.objs['lemon'][0] 34 | knife = self.objs['knife'][0] 35 | cabinet = self.objs['cabinet'][0] 36 | electric_refrigerator = self.objs['electric_refrigerator'][0] 37 | stove = self.objs['stove'][0] 38 | 39 | self.place_obj(cabinet) 40 | self.place_obj(electric_refrigerator) 41 | self.place_obj(stove) 42 | 43 | # place teapot, tea_bag, knife in cabinet 44 | pos_1, pos_2, pos_3 = self._rand_subset(cabinet.all_pos, 3) 45 | self.put_obj(teapot, *pos_1, 1) 46 | self.put_obj(tea_bag, *pos_2, 0) 47 | self.put_obj(knife, *pos_3, 0) 48 | 49 | for obj in [teapot, tea_bag, knife]: 50 | obj.states['inside'].set_value(cabinet, 'inside') 51 | 52 | # place lemon in fridge 53 | pos = self._rand_subset(electric_refrigerator.all_pos, 1)[0] 54 | self.put_obj(lemon, *pos, 1) 55 | lemon.states['inside'].set_value(electric_refrigerator, 'inside') 56 | 57 | def _init_conditions(self): 58 | for obj_type in ['teapot', 'tea_bag', 'lemon', 'knife', 'cabinet', 'electric_refrigerator', 'stove']: 59 | assert obj_type in self.objs.keys(), f"No {obj_type}" 60 | 61 | teapot = self.objs['teapot'][0] 62 | tea_bag = self.objs['tea_bag'][0] 63 | lemon = self.objs['lemon'][0] 64 | knife = self.objs['knife'][0] 65 | cabinet = self.objs['cabinet'][0] 66 | electric_refrigerator = self.objs['electric_refrigerator'][0] 67 | 68 | assert teapot.check_rel_state(self, cabinet, 'inside') 69 | assert tea_bag.check_rel_state(self, cabinet, 'inside') 70 | assert knife.check_rel_state(self, cabinet, 'inside') 71 | 72 | assert lemon.check_rel_state(self, electric_refrigerator, 'inside') 73 | 74 | return True 75 | 76 | 77 | 78 | def _end_conditions(self): 79 | teapot = self.objs['teapot'][0] 80 | tea_bag = self.objs['tea_bag'][0] 81 | lemon = self.objs['lemon'][0] 82 | stove = self.objs['stove'][0] 83 | 84 | if lemon.check_abs_state(self, 'sliceable') and \ 85 | teapot.check_rel_state(self, stove, 'onTop') and \ 86 | tea_bag.check_rel_state(self, teapot, 'atsamelocation') and \ 87 | tea_bag.check_abs_state(self, 'soakable') and \ 88 | stove.check_abs_state(self, 'toggleable'): 89 | return True 90 | 91 | return False 92 | 93 | 94 | # non human input env 95 | register( 96 | id='MiniGrid-MakingTea-16x16-N2-v0', 97 | entry_point='mini_behavior.envs:MakingTeaEnv' 98 | ) 99 | 100 | # human input env 101 | register( 102 | id='MiniGrid-MakingTea-16x16-N2-v1', 103 | entry_point='mini_behavior.envs:MakingTeaEnv', 104 | kwargs={'mode': 'cartesian'} 105 | ) 106 | -------------------------------------------------------------------------------- /mini_behavior/envs/moving_boxes_to_storage.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class MovingBoxesToStorageEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to clean a car 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | max_steps=1e5, 15 | ): 16 | num_objs = {'carton': 2, 'shelf': 1} 17 | 18 | self.mission = 'move boxes to storage' 19 | 20 | super().__init__(mode=mode, 21 | num_objs=num_objs, 22 | room_size=room_size, 23 | num_rows=1, 24 | num_cols=2, 25 | max_steps=max_steps 26 | ) 27 | 28 | def _gen_objs(self): 29 | cartons = self.objs['carton'] 30 | shelf = self.objs['shelf'][0] 31 | 32 | self.place_in_room(0, 0, cartons[0]) 33 | self.place_in_room(1, 0, cartons[1]) 34 | self.place_in_room(1, 0, shelf) 35 | 36 | # agent start in room 2 37 | 38 | def _init_conditions(self): 39 | for obj_type in ['carton', 'shelf']: 40 | assert obj_type in self.objs.keys(), f"No {obj_type}" 41 | 42 | return True 43 | 44 | 45 | 46 | def _end_conditions(self): 47 | cartons = self.objs['carton'] 48 | 49 | if cartons[0].check_abs_state(self, 'onfloor') and cartons[1].check_rel_state(self, 'onTop'): 50 | return True 51 | 52 | if cartons[1].check_abs_state(self, 'onfloor') and cartons[0].check_rel_state(self, 'onTop'): 53 | return True 54 | 55 | return False 56 | 57 | 58 | # non human input env 59 | register( 60 | id='MiniGrid-MovingBoxesToStorage-16x16-N2-v0', 61 | entry_point='mini_behavior.envs:MovingBoxesToStorageEnv' 62 | ) 63 | 64 | # human input env 65 | register( 66 | id='MiniGrid-MovingBoxesToStorage-16x16-N2-v1', 67 | entry_point='mini_behavior.envs:MovingBoxesToStorageEnv', 68 | kwargs={'mode': 'cartesian'} 69 | ) 70 | -------------------------------------------------------------------------------- /mini_behavior/envs/navigation.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class NavigationEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to navigate to a target position 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | num_objs=None 18 | ): 19 | if num_objs is None: 20 | num_objs = {'goal': 1} 21 | 22 | super().__init__(mode=mode, 23 | num_objs=num_objs, 24 | room_size=room_size, 25 | num_rows=num_rows, 26 | num_cols=num_cols, 27 | max_steps=max_steps 28 | ) 29 | 30 | def _gen_grid(self, width, height): 31 | self._gen_rooms(width, height) 32 | 33 | # generate goal position 34 | goal = self.objs['goal'][0] 35 | _, self.target_pos = self.place_in_room(0, 0, goal, reject_fn=None) 36 | goal.on_floor = True 37 | 38 | # generate other objects 39 | if 'ball' in self.objs.keys(): 40 | balls = self.objs['ball'] 41 | for ball in balls: 42 | self.place_in_room(0, 0, ball, reject_fn=None) 43 | 44 | # randomize the agent start position and orientation 45 | self.place_agent() 46 | self.mission = 'navigate to the target position' 47 | self.connect_all() 48 | 49 | def _end_conditions(self): 50 | if np.all(self.agent.cur_pos == self.target_pos): 51 | return True 52 | else: 53 | return False 54 | 55 | 56 | class NavigationEnv16x16_Human(NavigationEnv): 57 | def __init__(self): 58 | super().__init__(mode='cartesian', 59 | room_size=16, 60 | ) 61 | 62 | 63 | class NavigationMultiEnv16x16_Human(NavigationEnv): 64 | def __init__(self): 65 | super().__init__(mode='cartesian', 66 | room_size=16, 67 | num_rows=2, 68 | num_cols=2 69 | ) 70 | 71 | 72 | class NavigationMultiEnv16x16_RL(NavigationEnv): 73 | def __init__(self): 74 | super().__init__(mode='primitive', 75 | room_size=16, 76 | num_rows=2, 77 | num_cols=2 78 | ) 79 | 80 | class NavigationMultiEnv8x8_Human(NavigationEnv): 81 | def __init__(self): 82 | super().__init__(mode='cartesian', 83 | room_size=8, 84 | num_rows=2, 85 | num_cols=2 86 | ) 87 | 88 | 89 | # human control env 90 | register( 91 | id='MiniGrid-Navigation-16x16-N1-v0', 92 | entry_point='mini_behavior.envs:NavigationEnv16x16_Human' 93 | ) 94 | 95 | 96 | ##### MULTI ROOM 97 | # human control env 98 | register( 99 | id='MiniGrid-NavigationMulti-16x16-N1-v0', 100 | entry_point='mini_behavior.envs:NavigatioMultiEnv16x16_Human' 101 | ) 102 | 103 | # RL agent env 104 | register( 105 | id='MiniGrid-NavigationMulti-16x16-N2-v0', 106 | entry_point='mini_behavior.envs:NavigatioMultiEnv16x16_RL' 107 | ) 108 | 109 | # human control env 110 | register( 111 | id='MiniGrid-NavigationMulti-8x8-N1-v0', 112 | entry_point='mini_behavior.envs:NavigatioMultiEnv8x8_Human' 113 | ) 114 | -------------------------------------------------------------------------------- /mini_behavior/envs/opening_packages.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class OpeningPackagesEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to clean a car 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | num_objs=None 18 | ): 19 | if num_objs is None: 20 | num_objs = {'package': 2} 21 | 22 | self.mission = 'open packages' 23 | 24 | super().__init__(mode=mode, 25 | num_objs=num_objs, 26 | room_size=room_size, 27 | num_rows=num_rows, 28 | num_cols=num_cols, 29 | max_steps=max_steps 30 | ) 31 | 32 | def _gen_objs(self): 33 | for package in self.objs['package']: 34 | self.place_obj(package) 35 | package.states['openable'].set_value(False) 36 | 37 | def _init_conditions(self): 38 | for obj_type in ['package']: 39 | assert obj_type in self.objs.keys(), f"No {obj_type}" 40 | 41 | for package in self.objs['package']: 42 | assert not package.check_abs_state(self, 'openable') 43 | 44 | return True 45 | 46 | 47 | 48 | def _end_conditions(self): 49 | for package in self.objs['package']: 50 | if not package.check_abs_state(self, 'openable'): 51 | return False 52 | return True 53 | 54 | 55 | # non human input env 56 | register( 57 | id='MiniGrid-OpeningPackages-16x16-N2-v0', 58 | entry_point='mini_behavior.envs:OpeningPackagesEnv' 59 | ) 60 | 61 | # human input env 62 | register( 63 | id='MiniGrid-OpeningPackages-16x16-N2-v1', 64 | entry_point='mini_behavior.envs:OpeningPackagesEnv', 65 | kwargs={'mode': 'cartesian'} 66 | ) 67 | -------------------------------------------------------------------------------- /mini_behavior/envs/organizing_file_cabinet.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class OrganizingFileCabinetEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to clean a car 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | num_objs=None 18 | ): 19 | if num_objs is None: 20 | num_objs = {'marker': 1, 'chair': 1, 'document': 4, 'table': 1, 'cabinet': 1, 'folder': 2} 21 | 22 | self.mission = 'open packages' 23 | 24 | super().__init__(mode=mode, 25 | num_objs=num_objs, 26 | room_size=room_size, 27 | num_rows=num_rows, 28 | num_cols=num_cols, 29 | max_steps=max_steps 30 | ) 31 | 32 | def _gen_objs(self): 33 | chair = self.objs['chair'][0] 34 | table = self.objs['table'][0] 35 | cabinet = self.objs['cabinet'][0] 36 | marker = self.objs['marker'][0] 37 | folders = self.objs['folder'] 38 | documents = self.objs['document'] 39 | 40 | # place all furniture 41 | self.place_obj(chair) 42 | self.place_obj(table) 43 | self.place_obj(cabinet) 44 | 45 | pos_0, pos_1, pos_2 = self._rand_subset(table.all_pos, 3) 46 | pos_3, pos_4 = self._rand_subset(cabinet.all_pos, 2) 47 | 48 | # put marker on chair 49 | self.put_obj(marker, *chair.cur_pos, 1) 50 | 51 | # put documents 52 | self.put_obj(documents[0], *pos_0, 2) 53 | self.put_obj(documents[1], *pos_3, 0) 54 | self.put_obj(documents[2], *pos_1, 2) 55 | self.put_obj(documents[3], *pos_4, 1) 56 | 57 | # put folders 58 | self.put_obj(folders[0], *pos_2, 2) 59 | self.place_obj(folders[1]) 60 | 61 | def _init_conditions(self): 62 | for obj_type in ['chair', 'table', 'cabinet', 'marker', 'document', 'folder']: 63 | assert obj_type in self.objs.keys(), f"No {obj_type}" 64 | 65 | chair = self.objs['chair'][0] 66 | table = self.objs['table'][0] 67 | cabinet = self.objs['cabinet'][0] 68 | marker = self.objs['marker'][0] 69 | folders = self.objs['folder'] 70 | documents = self.objs['document'] 71 | 72 | assert marker.check_rel_state(self, chair, 'onTop') 73 | assert documents[0].check_rel_state(self, table, 'onTop') 74 | assert documents[1].check_rel_state(self, cabinet, 'inside') 75 | assert documents[2].check_rel_state(self, table, 'onTop') 76 | assert documents[3].check_rel_state(self, cabinet, 'inside') 77 | assert folders[0].check_rel_state(self, table, 'onTop') 78 | assert folders[1].check_abs_state(self, 'onfloor') 79 | 80 | return True 81 | 82 | 83 | 84 | def _end_conditions(self): 85 | chair = self.objs['chair'][0] 86 | table = self.objs['table'][0] 87 | cabinet = self.objs['cabinet'][0] 88 | marker = self.objs['marker'][0] 89 | folders = self.objs['folder'] 90 | documents = self.objs['document'] 91 | 92 | if not marker.check_rel_state(self, table, 'onTop'): 93 | return False 94 | 95 | for document in documents: 96 | if not document.check_rel_state(self, cabinet, 'inside'): 97 | return False 98 | 99 | for folder in folders: 100 | if not folder.check_rel_state(self, cabinet, 'inside'): 101 | return False 102 | 103 | return True 104 | 105 | 106 | # non human input env 107 | register( 108 | id='MiniGrid-OrganizingFileCabinet-16x16-N2-v0', 109 | entry_point='mini_behavior.envs:OrganizingFileCabinetEnv' 110 | ) 111 | 112 | # human input env 113 | register( 114 | id='MiniGrid-OrganizingFileCabinet-16x16-N2-v1', 115 | entry_point='mini_behavior.envs:OrganizingFileCabinetEnv', 116 | kwargs={'mode': 'cartesian'} 117 | ) 118 | -------------------------------------------------------------------------------- /mini_behavior/envs/preparing_salad.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class PreparingSaladEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to clean a car 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | ): 18 | num_objs = {'electric_refrigerator': 1, 'lettuce': 2, 'countertop': 1, 'apple': 2, 'tomato': 2, 19 | 'radish': 2, 'carving_knife': 1, 'plate': 2, 'cabinet': 1, 'sink': 1} 20 | 21 | self.mission = 'prepare salad' 22 | 23 | super().__init__(mode=mode, 24 | num_objs=num_objs, 25 | room_size=room_size, 26 | num_rows=num_rows, 27 | num_cols=num_cols, 28 | max_steps=max_steps 29 | ) 30 | 31 | def _gen_objs(self): 32 | electric_refrigerator = self.objs['electric_refrigerator'][0] 33 | lettuce = self.objs['lettuce'] 34 | countertop = self.objs['countertop'][0] 35 | apple = self.objs['apple'] 36 | tomato = self.objs['tomato'] 37 | radish = self.objs['radish'] 38 | carving_knife = self.objs['carving_knife'][0] 39 | plate = self.objs['plate'] 40 | cabinet = self.objs['cabinet'][0] 41 | sink = self.objs['sink'][0] 42 | 43 | self.place_obj(countertop) 44 | self.place_obj(electric_refrigerator) 45 | self.place_obj(cabinet) 46 | self.place_obj(sink) 47 | 48 | countertop_pos = self._rand_subset(countertop.all_pos, 6) 49 | self.put_obj(lettuce[0], *countertop_pos[0], 1) 50 | self.put_obj(lettuce[1], *countertop_pos[1], 1) 51 | self.put_obj(apple[0], *countertop_pos[2], 1) 52 | self.put_obj(apple[1], *countertop_pos[3], 1) 53 | 54 | fridge_pos = self._rand_subset(electric_refrigerator.all_pos, 2) 55 | self.put_obj(tomato[0], *fridge_pos[0], 0) 56 | self.put_obj(tomato[1], *fridge_pos[1], 2) 57 | 58 | self.put_obj(radish[0], *countertop_pos[4], 1) 59 | self.put_obj(radish[1], *countertop_pos[5], 1) 60 | 61 | cabinet_pos = self._rand_subset(cabinet.all_pos, 3) 62 | self.put_obj(plate[0], *cabinet_pos[0], 1) 63 | plate[0].states['dustyable'].set_value(False) 64 | self.put_obj(plate[1], *cabinet_pos[1], 2) 65 | plate[1].states['dustyable'].set_value(False) 66 | self.put_obj(carving_knife, *cabinet_pos[2], 0) 67 | 68 | 69 | 70 | def _end_conditions(self): 71 | lettuces = self.objs['lettuce'] 72 | apples = self.objs['apple'] 73 | tomatos = self.objs['tomato'] 74 | radishes = self.objs['radish'] 75 | plates = self.objs['plate'] 76 | 77 | def forpair(vegs): 78 | for veg in vegs: 79 | forpair = False 80 | for plate in plates: 81 | if veg.check_rel_state(self, plate, 'onTop'): 82 | forpair = True 83 | break 84 | if not forpair: 85 | return False 86 | 87 | for plate in plates: 88 | forpair = False 89 | for veg in vegs: 90 | if veg.check_rel_state(self, plate, 'onTop'): 91 | forpair = True 92 | break 93 | if not forpair: 94 | return False 95 | 96 | def forpair_slice(vegs): 97 | for veg in vegs: 98 | forpair = False 99 | for plate in plates: 100 | if plate.check_abs_state(self, 'sliced') and veg.check_rel_state(self, plate, 'onTop'): 101 | forpair = True 102 | break 103 | if not forpair: 104 | return False 105 | 106 | for plate in plates: 107 | forpair = False 108 | for veg in vegs: 109 | if veg.check_abs_state(self, 'sliced') and veg.check_rel_state(self, plate, 'onTop'): 110 | forpair = True 111 | break 112 | if not forpair: 113 | return False 114 | 115 | return True 116 | 117 | if not forpair(lettuces) or not forpair_slice(apples) or not forpair_slice(tomatos) or not forpair(radishes): 118 | return False 119 | 120 | return True 121 | 122 | 123 | # non human input env 124 | register( 125 | id='MiniGrid-PreparingSalad-16x16-N2-v0', 126 | entry_point='mini_behavior.envs:PreparingSaladEnv' 127 | ) 128 | 129 | # human input env 130 | register( 131 | id='MiniGrid-PreparingSalad-16x16-N2-v1', 132 | entry_point='mini_behavior.envs:PreparingSaladEnv', 133 | kwargs={'mode': 'cartesian'} 134 | ) 135 | -------------------------------------------------------------------------------- /mini_behavior/envs/preparing_salad_floorplan.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.floorplan import * 2 | from mini_behavior.register import register 3 | 4 | 5 | 6 | class PreparingSaladFloorplanEnv(FloorPlanEnv): 7 | """ 8 | Environment in which the agent is instructed to clean a car 9 | """ 10 | 11 | 12 | def __init__( 13 | self, 14 | mode='cartesian', 15 | scene_id='rs_int', 16 | num_objs=None, 17 | max_steps=1e5, 18 | ): 19 | num_objs = {'electric_refrigerator': 1, 'lettuce': 2, 'countertop': 1, 'apple': 2, 'tomato': 2, 20 | 'radish': 2, 'carving_knife': 1, 'plate': 2, 'cabinet': 1, 'sink': 1} 21 | 22 | self.mission = 'prepare salad' 23 | 24 | super().__init__(mode=mode, 25 | scene_id=scene_id, 26 | num_objs=num_objs, 27 | max_steps=max_steps 28 | ) 29 | 30 | def _gen_objs(self): 31 | electric_refrigerator = self.objs['electric_refrigerator'][0] 32 | lettuce = self.objs['lettuce'] 33 | countertop = self.objs['countertop'][0] 34 | apple = self.objs['apple'] 35 | tomato = self.objs['tomato'] 36 | radish = self.objs['radish'] 37 | carving_knife = self.objs['carving_knife'][0] 38 | plate = self.objs['plate'] 39 | cabinet = self.objs['cabinet'][0] 40 | sink = self.objs['sink'][0] 41 | 42 | self.objs['electric_refrigerator'][0].width = 4 * 2 43 | self.objs['electric_refrigerator'][0].height = 6 * 2 44 | 45 | self.objs['countertop'][0].width = 6 * 2 46 | self.objs['countertop'][0].height = 4 * 2 47 | 48 | self.objs['sink'][0].width = 4 * 2 49 | self.objs['sink'][0].height = 4 * 2 50 | 51 | self.place_obj(countertop) 52 | self.place_obj(electric_refrigerator) 53 | self.place_obj(cabinet) 54 | self.place_obj(sink) 55 | 56 | countertop_pos = self._rand_subset(countertop.all_pos, 6) 57 | self.put_obj(lettuce[0], *countertop_pos[0], 1) 58 | self.put_obj(lettuce[1], *countertop_pos[1], 1) 59 | self.put_obj(apple[0], *countertop_pos[2], 1) 60 | self.put_obj(apple[1], *countertop_pos[3], 1) 61 | 62 | fridge_pos = self._rand_subset(electric_refrigerator.all_pos, 2) 63 | self.put_obj(tomato[0], *fridge_pos[0], 0) 64 | self.put_obj(tomato[1], *fridge_pos[1], 2) 65 | 66 | self.put_obj(radish[0], *countertop_pos[4], 1) 67 | self.put_obj(radish[1], *countertop_pos[5], 1) 68 | 69 | cabinet_pos = self._rand_subset(cabinet.all_pos, 3) 70 | self.put_obj(plate[0], *cabinet_pos[0], 1) 71 | plate[0].states['dustyable'].set_value(False) 72 | self.put_obj(plate[1], *cabinet_pos[1], 2) 73 | plate[1].states['dustyable'].set_value(False) 74 | self.put_obj(carving_knife, *cabinet_pos[2], 0) 75 | 76 | 77 | 78 | def _end_conditions(self): 79 | lettuces = self.objs['lettuce'] 80 | apples = self.objs['apple'] 81 | tomatos = self.objs['tomato'] 82 | radishes = self.objs['radish'] 83 | plates = self.objs['plate'] 84 | 85 | def forpair(vegs): 86 | for veg in vegs: 87 | forpair = False 88 | for plate in plates: 89 | if veg.check_rel_state(self, plate, 'onTop'): 90 | forpair = True 91 | break 92 | if not forpair: 93 | return False 94 | 95 | for plate in plates: 96 | forpair = False 97 | for veg in vegs: 98 | if veg.check_rel_state(self, plate, 'onTop'): 99 | forpair = True 100 | break 101 | if not forpair: 102 | return False 103 | 104 | def forpair_slice(vegs): 105 | for veg in vegs: 106 | forpair = False 107 | for plate in plates: 108 | if plate.check_abs_state(self, 'sliced') and veg.check_rel_state(self, plate, 'onTop'): 109 | forpair = True 110 | break 111 | if not forpair: 112 | return False 113 | 114 | for plate in plates: 115 | forpair = False 116 | for veg in vegs: 117 | if veg.check_abs_state(self, 'sliced') and veg.check_rel_state(self, plate, 'onTop'): 118 | forpair = True 119 | break 120 | if not forpair: 121 | return False 122 | 123 | return True 124 | 125 | if not forpair(lettuces) or not forpair_slice(apples) or not forpair_slice(tomatos) or not forpair(radishes): 126 | return False 127 | 128 | return True 129 | 130 | 131 | # non human input env 132 | register( 133 | id='MiniGrid-PreparingSaladFloorplan-16x16-N2-v0', 134 | entry_point='mini_behavior.envs:PreparingSaladFloorplanEnv' 135 | ) 136 | 137 | # human input env 138 | register( 139 | id='MiniGrid-PreparingSaladFloorplan-16x16-N2-v1', 140 | entry_point='mini_behavior.envs:PreparingSaladFloorplanEnv', 141 | kwargs={'mode': 'cartesian'} 142 | ) 143 | -------------------------------------------------------------------------------- /mini_behavior/envs/putting_away_dishes_after_cleaning.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class PuttingAwayDishesAfterCleaningEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to put away dishes after cleaning 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | dense_reward=False, 18 | ): 19 | num_objs = {'plate': 8, 'countertop': 2, 'cabinet': 1} 20 | 21 | self.mission = 'put away dishes after cleaning' 22 | 23 | super().__init__(mode=mode, 24 | num_objs=num_objs, 25 | room_size=room_size, 26 | num_rows=num_rows, 27 | num_cols=num_cols, 28 | max_steps=max_steps, 29 | dense_reward=dense_reward, 30 | ) 31 | 32 | def _gen_objs(self): 33 | plate = self.objs['plate'] 34 | countertop = self.objs['countertop'] 35 | cabinet = self.objs['cabinet'][0] 36 | 37 | self.place_obj(countertop[0]) 38 | self.place_obj(countertop[1]) 39 | self.place_obj(cabinet) 40 | 41 | countertop_pos = self._rand_subset(countertop[0].all_pos, 4) + self._rand_subset(countertop[1].all_pos, 4) 42 | 43 | for i in range(8): 44 | self.put_obj(plate[i], *countertop_pos[i], 1) 45 | 46 | def _end_conditions(self): 47 | plate = self.objs['plate'] 48 | cabinet = self.objs['cabinet'][0] 49 | 50 | for obj in plate: 51 | if not obj.check_rel_state(self, cabinet, 'inside'): 52 | return False 53 | 54 | return True 55 | 56 | # This score measures progress towards the goal 57 | def get_progress(self): 58 | plate = self.objs['plate'] 59 | cabinet = self.objs['cabinet'][0] 60 | score = 0 61 | for obj in plate: 62 | if obj.check_rel_state(self, cabinet, 'inside'): 63 | score += 1 64 | if cabinet.check_abs_state(self, 'openable'): 65 | score += 1 66 | 67 | return score 68 | 69 | 70 | # non human input env 71 | register( 72 | id='MiniGrid-PuttingAwayDishesAfterCleaning-16x16-N2-v0', 73 | entry_point='mini_behavior.envs:PuttingAwayDishesAfterCleaningEnv' 74 | ) 75 | 76 | # non human input env 77 | register( 78 | id='MiniGrid-PuttingAwayDishesAfterCleaningDense-10x10-N2-v0', 79 | entry_point='mini_behavior.envs:PuttingAwayDishesAfterCleaningEnv', 80 | kwargs={'room_size': 10, 'max_steps': 1000, 'dense_reward': True} 81 | ) 82 | 83 | # human input env 84 | register( 85 | id='MiniGrid-PuttingAwayDishesAfterCleaning-16x16-N2-v1', 86 | entry_point='mini_behavior.envs:PuttingAwayDishesAfterCleaningEnv', 87 | kwargs={'mode': 'cartesian'} 88 | ) 89 | -------------------------------------------------------------------------------- /mini_behavior/envs/setting_up_candles.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class SettingUpCandlesEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to clean a car 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | max_steps=1e5, 15 | ): 16 | num_objs = {'candle': 6, 'table': 2, 'box': 2} 17 | 18 | self.mission = 'set up candles' 19 | 20 | super().__init__(mode=mode, 21 | num_objs=num_objs, 22 | room_size=room_size, 23 | num_rows=1, 24 | num_cols=2, 25 | max_steps=max_steps 26 | ) 27 | 28 | def _gen_objs(self): 29 | candle = self.objs['candle'] 30 | table = self.objs['table'] 31 | box = self.objs['box'] 32 | 33 | self.place_in_room(0, 0, table[0]) 34 | self.place_in_room(1, 0, table[1]) 35 | 36 | self.place_in_room(0, 0, box[0]) 37 | self.place_in_room(0, 0, box[1]) 38 | 39 | box_pos = self._rand_subset(box[0].all_pos, 3) + self._rand_subset(box[1].all_pos, 3) 40 | 41 | for i in range(6): 42 | self.put_obj(candle[i], *box_pos[i], 0) 43 | 44 | for obj in candle[:3]: 45 | obj.states['inside'].set_value(box[0], True) 46 | 47 | for obj in candle[3:]: 48 | obj.states['inside'].set_value(box[1], True) 49 | 50 | 51 | 52 | def _end_conditions(self): 53 | candle = self.objs['candle'] 54 | table = self.objs['table'] 55 | 56 | n_0 = 0 57 | n_1 = 0 58 | for obj in candle: 59 | if obj.check_rel_state(self, table[0], 'onTop'): 60 | n_0 += 1 61 | elif obj.check_rel_state(self, table[1], 'onTop'): 62 | n_1 += 1 63 | 64 | return n_0 == 3 and n_1 == 3 65 | 66 | 67 | # non human input env 68 | register( 69 | id='MiniGrid-SettingUpCandles-16x16-N2-v0', 70 | entry_point='mini_behavior.envs:SettingUpCandlesEnv' 71 | ) 72 | 73 | # human input env 74 | register( 75 | id='MiniGrid-SettingUpCandles-16x16-N2-v1', 76 | entry_point='mini_behavior.envs:SettingUpCandlesEnv', 77 | kwargs={'mode': 'cartesian'} 78 | ) 79 | -------------------------------------------------------------------------------- /mini_behavior/envs/sorting_books.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class SortingBooksEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to clean a car 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | ): 18 | num_objs = {'book': 2, 'hardback': 2, 'table': 1, 'shelf': 1} 19 | 20 | self.mission = 'sort books' 21 | 22 | super().__init__(mode=mode, 23 | num_objs=num_objs, 24 | room_size=room_size, 25 | num_rows=num_rows, 26 | num_cols=num_cols, 27 | max_steps=max_steps 28 | ) 29 | 30 | def _gen_objs(self): 31 | book = self.objs['book'] 32 | hardback = self.objs['hardback'] 33 | table = self.objs['table'][0] 34 | shelf = self.objs['shelf'][0] 35 | 36 | self.place_obj(table) 37 | self.place_obj(shelf) 38 | self.place_obj(book[0]) 39 | self.place_obj(hardback[0]) 40 | 41 | table_pos = self._rand_subset(table.all_pos, 2) 42 | self.put_obj(book[1], *table_pos[0], 2) 43 | self.put_obj(hardback[1], *table_pos[1], 2) 44 | 45 | 46 | 47 | def _end_conditions(self): 48 | book = self.objs['book'] 49 | hardback = self.objs['hardback'] 50 | shelf = self.objs['shelf'][0] 51 | 52 | for obj in book + hardback: 53 | if not obj.check_rel_state(self, shelf, 'onTop'): 54 | return False 55 | 56 | return True 57 | 58 | 59 | # non human input env 60 | register( 61 | id='MiniGrid-SortingBooks-16x16-N2-v0', 62 | entry_point='mini_behavior.envs:SortingBooksEnv' 63 | ) 64 | 65 | # human input env 66 | register( 67 | id='MiniGrid-SortingBooks-16x16-N2-v1', 68 | entry_point='mini_behavior.envs:SortingBooksEnv', 69 | kwargs={'mode': 'cartesian'} 70 | ) 71 | -------------------------------------------------------------------------------- /mini_behavior/envs/storing_food.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class StoringFoodEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to clean a car 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | ): 18 | num_objs = {'oatmeal': 2, 'countertop': 1, 'chip': 2, 'vegetable_oil': 2, 19 | 'sugar': 2, 'cabinet': 1} 20 | 21 | self.mission = 'store food' 22 | 23 | super().__init__(mode=mode, 24 | num_objs=num_objs, 25 | room_size=room_size, 26 | num_rows=num_rows, 27 | num_cols=num_cols, 28 | max_steps=max_steps 29 | ) 30 | 31 | def _gen_objs(self): 32 | oatmeals = self.objs['oatmeal'] 33 | chips = self.objs['chip'] 34 | countertop = self.objs['countertop'][0] 35 | vegetable_oils = self.objs['vegetable_oil'] 36 | sugars = self.objs['sugar'] 37 | cabinet = self.objs['cabinet'][0] 38 | 39 | countertop.width, countertop.height = 4, 3 40 | 41 | self.place_obj(countertop) 42 | self.place_obj(cabinet) 43 | 44 | countertop_pos = self._rand_subset(countertop.all_pos, 8) 45 | self.put_obj(oatmeals[0], *countertop_pos[0], 1) 46 | self.put_obj(oatmeals[1], *countertop_pos[1], 1) 47 | self.put_obj(chips[0], *countertop_pos[2], 1) 48 | self.put_obj(chips[1], *countertop_pos[3], 1) 49 | self.put_obj(vegetable_oils[0], *countertop_pos[4], 1) 50 | self.put_obj(vegetable_oils[1], *countertop_pos[5], 1) 51 | self.put_obj(sugars[0], *countertop_pos[6], 1) 52 | self.put_obj(sugars[1], *countertop_pos[7], 1) 53 | 54 | 55 | 56 | def _end_conditions(self): 57 | oatmeals = self.objs['oatmeal'] 58 | chips = self.objs['chip'] 59 | vegetable_oils = self.objs['vegetable_oil'] 60 | sugars = self.objs['sugar'] 61 | cabinet = self.objs['cabinet'][0] 62 | 63 | for obj in oatmeals + chips + vegetable_oils + sugars: 64 | if not obj.check_rel_state(self, cabinet, 'inside'): 65 | return False 66 | 67 | return True 68 | 69 | 70 | # non human input env 71 | register( 72 | id='MiniGrid-StoringFood-16x16-N2-v0', 73 | entry_point='mini_behavior.envs:StoringFoodEnv' 74 | ) 75 | 76 | # human input env 77 | register( 78 | id='MiniGrid-StoringFood-16x16-N2-v1', 79 | entry_point='mini_behavior.envs:StoringFoodEnv', 80 | kwargs={'mode': 'cartesian'} 81 | ) 82 | -------------------------------------------------------------------------------- /mini_behavior/envs/thawing_frozen_food.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class ThawingFrozenFoodEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to clean a car 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | ): 18 | num_objs = {'date': 1, 'electric_refrigerator': 1, 'olive': 1, 'fish': 4, 'sink': 1} 19 | 20 | self.mission = 'thaw frozen food' 21 | 22 | super().__init__(mode=mode, 23 | num_objs=num_objs, 24 | room_size=room_size, 25 | num_rows=num_rows, 26 | num_cols=num_cols, 27 | max_steps=max_steps 28 | ) 29 | 30 | def _gen_objs(self): 31 | date = self.objs['date'] 32 | olive = self.objs['olive'] 33 | fish = self.objs['fish'] 34 | electric_refrigerator = self.objs['electric_refrigerator'][0] 35 | sink = self.objs['sink'][0] 36 | 37 | self.place_obj(electric_refrigerator) 38 | self.place_obj(sink) 39 | 40 | fridge_pos = self._rand_subset(electric_refrigerator.all_pos, 4) 41 | self.put_obj(date[0], *fridge_pos[0], 1) 42 | self.put_obj(olive[0], *fridge_pos[1], 1) 43 | self.put_obj(fish[0], *fridge_pos[2], 2) 44 | self.put_obj(fish[1], *fridge_pos[3], 1) 45 | self.put_obj(fish[2], *fridge_pos[0], 0) 46 | self.put_obj(fish[3], *fridge_pos[2], 2) 47 | 48 | for obj in date + olive + fish: 49 | obj.states['inside'].set_value(electric_refrigerator, True) 50 | 51 | 52 | 53 | def _init_conditions(self): 54 | for obj in self.objs['date'] + self.objs['olive'] + self.objs['fish']: 55 | assert obj.check_abs_state(self, 'freezable') 56 | 57 | def _end_conditions(self): 58 | date = self.objs['date'][0] 59 | olive = self.objs['olive'][0] 60 | fishes = self.objs['fish'] 61 | sink = self.objs['sink'][0] 62 | 63 | nextto = False 64 | for fish in fishes: 65 | if date.check_rel_state(self, fish, 'nextto'): 66 | nextto = True 67 | 68 | if not nextto: 69 | return False 70 | 71 | for fish in fishes: 72 | if not fish.check_rel_state(self, sink, 'nextto'): 73 | return False 74 | 75 | if not olive.check_rel_state(self, sink, 'nextto'): 76 | return False 77 | 78 | return True 79 | 80 | 81 | # non human input env 82 | register( 83 | id='MiniGrid-ThawingFrozenFood-16x16-N2-v0', 84 | entry_point='mini_behavior.envs:ThawingFrozenFoodEnv' 85 | ) 86 | 87 | # human input env 88 | register( 89 | id='MiniGrid-ThawingFrozenFood-16x16-N2-v1', 90 | entry_point='mini_behavior.envs:ThawingFrozenFoodEnv', 91 | kwargs={'mode': 'cartesian'} 92 | ) 93 | -------------------------------------------------------------------------------- /mini_behavior/envs/throwing_away_leftovers.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class ThrowingAwayLeftoversEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to throw away all leftovers into a trash can. 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | num_objs=None 18 | ): 19 | if num_objs is None: 20 | num_objs = {'countertop': 1, 21 | 'plate': 4, 22 | 'hamburger': 3, 23 | 'ashcan': 1} 24 | 25 | self.mission = 'throw all {} leftovers in the ashcan'.format(num_objs['hamburger']) 26 | 27 | super().__init__(mode=mode, 28 | num_objs=num_objs, 29 | room_size=room_size, 30 | num_rows=num_rows, 31 | num_cols=num_cols, 32 | max_steps=max_steps 33 | ) 34 | 35 | def _gen_objs(self): 36 | countertop = self.objs['countertop'][0] 37 | plates = self.objs['plate'] 38 | hamburgers = self.objs['hamburger'] 39 | ashcan = self.objs['ashcan'][0] 40 | 41 | # place countertop 42 | self.place_obj(countertop) 43 | 44 | # place plates 45 | i = 0 46 | for pos in self._rand_subset(countertop.all_pos, len(plates)): 47 | self.put_obj(plates[i], *pos, 1) 48 | i += 1 49 | 50 | # place hamburgers 51 | i = 0 52 | for plate in self._rand_subset(plates, len(hamburgers)): 53 | self.put_obj(hamburgers[i], *plate.cur_pos, 2) 54 | i += 1 55 | 56 | # generate ashcan on floor 57 | self.target_pos = self.place_obj(ashcan) 58 | 59 | # TODO: automatically generate function from BDDL 60 | def _init_conditions(self): 61 | assert 'counter' in self.objs.keys(), "No counter" 62 | assert 'ashcan' in self.objs.keys(), "No ashcan" 63 | assert 'plate' in self.objs.keys(), "No plates" 64 | assert 'hamburger' in self.objs.keys(), "No hamburgers" 65 | 66 | countertop = self.objs['countertop'][0] 67 | plates = self.objs['plate'] 68 | hamburgers = self.objs['hamburger'] 69 | ashcan = self.objs['ashcan'][0] 70 | 71 | assert ashcan.check_abs_state(self, 'onfloor'), "Ashcan not on floor" 72 | 73 | for plate in plates: 74 | on_counter = plate.check_rel_state(self, countertop, 'onTop') 75 | assert on_counter, "Plate not on counter" 76 | 77 | for hamburger in hamburgers: 78 | on_plate = False 79 | for plate in plates: 80 | on_plate = hamburger.check_rel_state(self, plate, 'onTop') 81 | if on_plate: 82 | break 83 | assert on_plate, "Hamburger not on plate" 84 | 85 | return True 86 | 87 | def _reward(self): 88 | # fraction of hamburgers thrown away 89 | num_thrown = 0 90 | for hamburger in self.objs['hamburger']: 91 | is_inside = [hamburger.check_rel_state(self, ashcan, 'inside') for ashcan in self.objs['ashcan']] 92 | if True in is_inside: 93 | num_thrown += 1 94 | 95 | return num_thrown / len(self.objs['hamburger']) 96 | 97 | def _end_conditions(self): 98 | for hamburger in self.objs['hamburger']: 99 | is_inside = [hamburger.check_rel_state(self, ashcan, 'inside') for ashcan in self.objs['ashcan']] 100 | if True not in is_inside: 101 | return False 102 | return True 103 | 104 | register( 105 | id='MiniGrid-ThrowingAwayLeftovers-16x16-N2-v0', 106 | entry_point='mini_behavior.envs:ThrowingAwayLeftoversEnv' 107 | ) 108 | 109 | register( 110 | id='MiniGrid-ThrowingAwayLeftovers-16x16-N2-v1', 111 | entry_point='mini_behavior.envs:ThrowingAwayLeftoversEnv', 112 | kwargs={'mode': 'cartesian'} 113 | ) 114 | 115 | register( 116 | id='MiniGrid-ThrowingAwayLeftoversFour-8x8-N2-v0', 117 | entry_point='mini_behavior.envs:ThrowingAwayLeftoversEnv', 118 | kwargs={'mode': 'primitive', 119 | 'room_size': 8, 120 | 'num_rows': 2, 121 | 'num_cols': 2} 122 | ) 123 | 124 | register( 125 | id='MiniGrid-ThrowingAwayLeftoversFour-8x8-N2-v1', 126 | entry_point='mini_behavior.envs:ThrowingAwayLeftoversEnv', 127 | kwargs={'mode': 'cartesian', 128 | 'room_size': 8, 129 | 'num_rows': 2, 130 | 'num_cols': 2} 131 | ) 132 | 133 | register( 134 | id='MiniGrid-ThrowingAwayLeftovers-8x8-N2-v0', 135 | entry_point='mini_behavior.envs:ThrowingAwayLeftoversEnv', 136 | kwargs={'mode': 'primitive', 137 | 'room_size': 8} 138 | ) 139 | -------------------------------------------------------------------------------- /mini_behavior/envs/throwleftovers_floorplan.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.floorplan import * 2 | from mini_behavior.register import register 3 | import os 4 | 5 | 6 | class ThrowLeftoversSceneEnv(FloorPlanEnv): 7 | """ 8 | Environment in which the agent is instructed to throw away all leftovers into a trash can. 9 | """ 10 | 11 | def __init__( 12 | self, 13 | mode='cartesian', 14 | scene_id='rs_int', 15 | num_objs=None, 16 | max_steps=1e5, 17 | ): 18 | if num_objs is None: 19 | num_objs = {'countertop': 1, 20 | 'plate': 4, 21 | 'hamburger': 3, 22 | 'ashcan': 1} 23 | 24 | self.mission = 'throw all {} leftovers in the ashcan'.format(num_objs['hamburger']) 25 | 26 | super().__init__(mode=mode, 27 | scene_id=scene_id, 28 | num_objs=num_objs, 29 | max_steps=max_steps 30 | ) 31 | 32 | def _gen_objs(self): 33 | # # generate counter 34 | # place all objects 35 | countertop = self.objs['countertop'][0] 36 | plates = self.objs['plate'] 37 | hamburgers = self.objs['hamburger'] 38 | ashcan = self.objs['ashcan'][0] 39 | 40 | # place countertop 41 | self.place_obj(countertop) 42 | 43 | # place plates 44 | i = 0 45 | for pos in self._rand_subset(countertop.all_pos, len(plates)): 46 | self.put_obj(plates[i], *pos, 1) 47 | i += 1 48 | 49 | # place hamburgers 50 | i = 0 51 | for plate in self._rand_subset(plates, len(hamburgers)): 52 | self.put_obj(hamburgers[i], *plate.cur_pos, 2) 53 | i += 1 54 | 55 | # generate ashcan on floor 56 | self.target_pos = self.place_obj(ashcan) 57 | 58 | def _init_conditions(self): 59 | assert 'countertop' in self.objs.keys(), "No counter" 60 | assert 'ashcan' in self.objs.keys(), "No ashcan" 61 | assert 'plate' in self.objs.keys(), "No plates" 62 | assert 'hamburger' in self.objs.keys(), "No hamburgers" 63 | 64 | countertop = self.objs['countertop'][0] 65 | plates = self.objs['plate'] 66 | hamburgers = self.objs['hamburger'] 67 | ashcan = self.objs['ashcan'][0] 68 | 69 | assert ashcan.check_abs_state(self, 'onfloor'), "Ashcan not on floor" 70 | 71 | for plate in plates: 72 | on_counter = plate.check_rel_state(self, countertop, 'onTop') 73 | assert on_counter, "Plate not on counter" 74 | 75 | for hamburger in hamburgers: 76 | on_plate = False 77 | for plate in plates: 78 | on_plate = hamburger.check_rel_state(self, plate, 'onTop') 79 | if on_plate: 80 | break 81 | assert on_plate, "Hamburger not on plate" 82 | 83 | return True 84 | 85 | def _reward(self): 86 | # fraction of hamburgers thrown away 87 | num_thrown = 0 88 | for hamburger in self.objs['hamburger']: 89 | is_inside = [hamburger.check_rel_state(self, ashcan, 'inside') for ashcan in self.objs['ashcan']] 90 | if True in is_inside: 91 | num_thrown += 1 92 | 93 | return num_thrown / len(self.objs['hamburger']) 94 | 95 | def _end_conditions(self): 96 | for hamburger in self.objs['hamburger']: 97 | is_inside = [hamburger.check_rel_state(self, ashcan, 'inside') for ashcan in self.objs['ashcan']] 98 | if True not in is_inside: 99 | return False 100 | return True 101 | 102 | 103 | register( 104 | id='MiniGrid-ThrowLeftoversSceneEnv-0x0-N2-v0', 105 | entry_point='mini_behavior.envs:ThrowLeftoversSceneEnv', 106 | kwargs={} 107 | ) 108 | -------------------------------------------------------------------------------- /mini_behavior/envs/transition.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | from mini_behavior.objects import OBJECT_CLASS 4 | 5 | DEFAULT_OBJS = ['countertop', 'plate', 'ashcan', 'hamburger', 'ball', 'apple', 'carton', 'juice'] 6 | 7 | 8 | def create_transition_matrices(objs, num_rooms): 9 | """ 10 | return dict transitions, where transitions[obj] is the transition matrix for any obj in objs. 11 | the probability of obj going from room i --> j is: transitions[obj][i, j] 12 | """ 13 | transitions = {} 14 | for obj in objs: 15 | probs = np.random.rand(num_rooms, num_rooms) 16 | probs /= np.expand_dims(np.sum(probs, axis=1), 1) 17 | transitions[obj] = probs 18 | 19 | return transitions 20 | 21 | 22 | class TransitionEnv(RoomGrid): 23 | """ 24 | at every episode, randomly sample num_choose objects from given object list 25 | at every step, place objects in rooms based on matrix of transition probabilities 26 | """ 27 | 28 | def __init__( 29 | self, 30 | objs=None, 31 | transition_probs=None, 32 | num_choose=4, 33 | mode='primitive', 34 | room_size=8, 35 | num_rows=2, 36 | num_cols=2, 37 | max_steps=10, 38 | seed=1337 39 | ): 40 | if objs is None: 41 | objs = DEFAULT_OBJS 42 | 43 | self.available_objs = objs 44 | self.num_choose = num_choose 45 | self.num_rooms = num_rows * num_cols 46 | 47 | # generate matrix 48 | if transition_probs is None: 49 | self.transition_probs = create_transition_matrices(objs, self.num_rooms) 50 | else: 51 | for obj in objs: 52 | assert obj in transition_probs.keys(), f'{obj} missing transition matrix' 53 | assert np.all(np.shape(transition_probs[obj]) == np.array([self.num_rooms, self.num_rooms])), f'{obj} matrix has incorrect dimensions' 54 | self.transition_probs = transition_probs 55 | 56 | # randomly pick num_choose objs 57 | self.seed(seed=seed) 58 | chosen_objs = self._rand_subset(objs, num_choose) 59 | 60 | # initialize num_objs, key=obj name (str), value=num of the obj (1) 61 | num_objs = {obj: 1 for obj in chosen_objs} 62 | 63 | super().__init__(mode=mode, 64 | num_objs=num_objs, 65 | room_size=room_size, 66 | num_rows=num_rows, 67 | num_cols=num_cols, 68 | max_steps=max_steps, 69 | seed=seed 70 | ) 71 | 72 | self.mission = 'find the objs as they transition between rooms' 73 | 74 | actions = {'left': 0, 75 | 'right': 1, 76 | 'forward': 2} 77 | 78 | self.actions = IntEnum('Actions', actions) 79 | 80 | def choose_objs(self): 81 | chosen_objs = self._rand_subset(self.available_objs, self.num_choose) 82 | num_objs = {obj: 1 for obj in chosen_objs} 83 | 84 | # initialize num_objs, key=obj name (str), value=num of the obj (1) 85 | return num_objs 86 | 87 | def reset(self): 88 | num_objs = self.choose_objs() 89 | 90 | self.objs = {} 91 | self.obj_instances = {} 92 | for obj in num_objs.keys(): 93 | self.objs[obj] = [] 94 | for i in range(num_objs[obj]): 95 | obj_name = '{}_{}'.format(obj, i) 96 | obj_instance = OBJECT_CLASS[obj](obj_name) 97 | self.objs[obj].append(obj_instance) 98 | self.obj_instances[obj_name] = obj_instance 99 | 100 | super().reset() 101 | 102 | def _gen_objs(self): 103 | # randomly place objs on the grid 104 | for obj in self.obj_instances.values(): 105 | self.place_obj(obj) 106 | 107 | def step(self, action): 108 | super().step(action) 109 | 110 | # use transition prob to decide what room the obj should be in 111 | for obj in self.obj_instances.values(): 112 | if obj.type != 'door': 113 | cur_room = self.room_num_from_pos(*obj.cur_pos) # int 114 | probs = self.transition_probs[obj.get_class()][cur_room] 115 | new_room = np.random.choice(self.num_rooms, 1, p=probs)[0] # int 116 | room_idx = self.room_idx_from_num(new_room) # tuple 117 | self.grid.remove(*obj.cur_pos, obj) # remove obj from grid 118 | self.place_in_room(*room_idx, obj) # add obj to grid 119 | 120 | obs = self.gen_obs() 121 | reward = self._reward() 122 | done = self._end_conditions() 123 | return obs, reward, done, {} 124 | 125 | def _end_conditions(self): 126 | return self.step_count == self.max_steps 127 | 128 | 129 | register( 130 | id='MiniGrid-TransitionEnv-8x8x4-N2-v0', 131 | entry_point='mini_behavior.envs:TransitionEnv', 132 | ) 133 | 134 | register( 135 | id='MiniGrid-TransitionEnv-8x8x4-N2-v1', 136 | entry_point='mini_behavior.envs:TransitionEnv', 137 | kwargs={'mode': 'cartesian'} 138 | ) 139 | -------------------------------------------------------------------------------- /mini_behavior/envs/two_room_nav.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class TwoRoomNavigationEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to navigate to a target position 8 | """ 9 | 10 | # Enumeration of possible actions 11 | class Actions(IntEnum): 12 | # Turn left, turn right, move forward 13 | left = 0 14 | right = 1 15 | forward = 2 16 | 17 | def __init__( 18 | self, 19 | max_steps=1e5, 20 | ): 21 | super().__init__(mode='cartesian', 22 | num_objs={'ball': 1}, 23 | room_size=8, 24 | num_rows=1, 25 | num_cols=2, 26 | max_steps=max_steps, 27 | see_through_walls=True, 28 | agent_view_size=3, 29 | highlight=False 30 | ) 31 | 32 | def _gen_grid(self, width, height): 33 | self._gen_rooms(width, height) 34 | # randomize the agent start position and orientation 35 | self._gen_objs() 36 | self.place_agent() 37 | self.connect_all() 38 | self.mission = 'navigate between rooms' 39 | 40 | def _gen_objs(self): 41 | for obj in self.obj_instances.values(): 42 | self.place_obj(obj) 43 | 44 | def _end_conditions(self): 45 | return False 46 | 47 | 48 | register( 49 | id='MiniGrid-TwoRoomNavigation-8x8-N2-v0', 50 | entry_point='mini_behavior.envs:TwoRoomNavigationEnv' 51 | ) 52 | -------------------------------------------------------------------------------- /mini_behavior/envs/washing_pots_and_pans.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class WashingPotsAndPansEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to wash pots and pans 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | num_rows=1, 15 | num_cols=1, 16 | max_steps=1e5, 17 | dense_reward=False, 18 | ): 19 | num_objs = {'teapot': 1, 'kettle': 1, 'pan': 3, 'countertop': 2, 'sink': 1, 'scrub_brush': 1, 'soap': 1, 'cabinet': 2} 20 | 21 | self.mission = 'wash pots and pans' 22 | 23 | super().__init__(mode=mode, 24 | num_objs=num_objs, 25 | room_size=room_size, 26 | num_rows=num_rows, 27 | num_cols=num_cols, 28 | max_steps=max_steps, 29 | dense_reward=dense_reward, 30 | ) 31 | 32 | def _gen_objs(self): 33 | teapot = self.objs['teapot'][0] 34 | kettle = self.objs['kettle'][0] 35 | pans = self.objs['pan'] 36 | countertops = self.objs['countertop'] 37 | sink = self.objs['sink'][0] 38 | scrub_brush = self.objs['scrub_brush'][0] 39 | soap = self.objs['soap'][0] 40 | cabinets = self.objs['cabinet'] 41 | 42 | self.place_obj(countertops[0]) 43 | self.place_obj(countertops[1]) 44 | self.place_obj(cabinets[0]) 45 | self.place_obj(cabinets[1]) 46 | self.place_obj(sink) 47 | 48 | countertop_0_pos = self._rand_subset(countertops[0].all_pos, 3) 49 | countertop_1_pos = self._rand_subset(countertops[1].all_pos, 3) 50 | 51 | self.put_obj(teapot, *countertop_0_pos[0], 1) 52 | teapot.states['stainable'].set_value(True) 53 | self.put_obj(kettle, *countertop_1_pos[0], 1) 54 | kettle.states['stainable'].set_value(True) 55 | self.put_obj(pans[0], *countertop_0_pos[1], 1) 56 | pans[0].states['stainable'].set_value(True) 57 | self.put_obj(pans[1], *countertop_0_pos[2], 1) 58 | pans[1].states['stainable'].set_value(True) 59 | self.put_obj(pans[2], *countertop_1_pos[1], 1) 60 | pans[2].states['stainable'].set_value(True) 61 | 62 | self.put_obj(scrub_brush, *countertop_1_pos[2], 1) 63 | scrub_brush.states['soakable'].set_value(True) 64 | 65 | self.put_obj(soap, *sink.cur_pos, 0) 66 | soap.states['inside'].set_value(sink, True) 67 | 68 | def _end_conditions(self): 69 | teapots = self.objs['teapot'] 70 | kettles = self.objs['kettle'] 71 | pans = self.objs['pan'] 72 | 73 | for obj in pans + kettles + teapots: 74 | if obj.check_abs_state(self, 'stainable'): 75 | return False 76 | 77 | if obj.inside_of is None or type(obj.inside_of) != Cabinet: 78 | return False 79 | 80 | return True 81 | 82 | # This score measures progress towards the goal 83 | def get_progress(self): 84 | teapots = self.objs['teapot'] 85 | kettles = self.objs['kettle'] 86 | pans = self.objs['pan'] 87 | 88 | score = 0 89 | for obj in pans + kettles + teapots: 90 | if not obj.check_abs_state(self, 'stainable'): 91 | score += 1 92 | 93 | if obj.inside_of is not None and type(obj.inside_of) == Cabinet: 94 | score += 1 95 | 96 | for cab in self.objs['cabinet']: 97 | if cab.check_abs_state(self, 'openable'): 98 | score += 1 99 | 100 | return score 101 | 102 | 103 | # non human input env 104 | register( 105 | id='MiniGrid-WashingPotsAndPans-16x16-N2-v0', 106 | entry_point='mini_behavior.envs:WashingPotsAndPansEnv' 107 | ) 108 | 109 | # non human input env 110 | register( 111 | id='MiniGrid-WashingPotsAndPansDense-10x10-N2-v0', 112 | entry_point='mini_behavior.envs:WashingPotsAndPansEnv', 113 | kwargs={'room_size': 10, 'max_steps': 1000, 'dense_reward': True} 114 | ) 115 | 116 | # human input env 117 | register( 118 | id='MiniGrid-WashingPotsAndPans-16x16-N2-v1', 119 | entry_point='mini_behavior.envs:WashingPotsAndPansEnv', 120 | kwargs={'mode': 'cartesian'} 121 | ) 122 | -------------------------------------------------------------------------------- /mini_behavior/envs/watering_houseplants.py: -------------------------------------------------------------------------------- 1 | from mini_behavior.roomgrid import * 2 | from mini_behavior.register import register 3 | 4 | 5 | class WateringHouseplantsEnv(RoomGrid): 6 | """ 7 | Environment in which the agent is instructed to clean a car 8 | """ 9 | 10 | def __init__( 11 | self, 12 | mode='primitive', 13 | room_size=16, 14 | max_steps=1e5, 15 | ): 16 | num_objs = {'pot_plant': 3, 'sink': 1, 'table': 1, 'countertop': 1} 17 | 18 | self.mission = 'water houseplants' 19 | 20 | super().__init__(mode=mode, 21 | num_objs=num_objs, 22 | room_size=room_size, 23 | num_rows=1, 24 | num_cols=2, 25 | max_steps=max_steps 26 | ) 27 | 28 | def _gen_objs(self): 29 | pot_plants = self.objs['pot_plant'] 30 | sink = self.objs['sink'][0] 31 | table = self.objs['table'][0] 32 | countertop = self.objs['countertop'][0] 33 | 34 | self.place_in_room(0, 0, table) 35 | self.place_in_room(1, 0, countertop) 36 | self.place_in_room(1, 0, sink) 37 | 38 | self.place_in_room(0, 0, pot_plants[0]) 39 | self.place_in_room(0, 0, pot_plants[1]) 40 | self.place_in_room(1, 0, pot_plants[2]) 41 | 42 | for plant in pot_plants: 43 | plant.states['soakable'].set_value(False) 44 | 45 | # TODO: agent start in room 2 46 | 47 | 48 | 49 | def _end_conditions(self): 50 | pot_plants = self.objs['pot_plant'] 51 | 52 | for plant in pot_plants: 53 | if not plant.check_abs_state(self, 'soakable'): 54 | return False 55 | 56 | return True 57 | 58 | 59 | # non human input env 60 | register( 61 | id='MiniGrid-WateringHouseplants-16x16-N2-v0', 62 | entry_point='mini_behavior.envs:WateringHouseplantsEnv' 63 | ) 64 | 65 | # human input env 66 | register( 67 | id='MiniGrid-WateringHouseplants-16x16-N2-v1', 68 | entry_point='mini_behavior.envs:WateringHouseplantsEnv', 69 | kwargs={'mode': 'cartesian'} 70 | ) 71 | -------------------------------------------------------------------------------- /mini_behavior/floorplan.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | from mini_behavior.minibehavior import MiniBehaviorEnv 4 | from mini_behavior.grid import BehaviorGrid 5 | from mini_behavior.register import register 6 | from mini_behavior.objects import Wall 7 | from mini_behavior.utils.scene_to_grid import img_to_array 8 | 9 | FLOORPLANS_DIR = os.path.join(os.path.dirname(os.path.abspath(__name__)), "mini_behavior", "floorplans") 10 | 11 | 12 | def get_floorplan(scene_id) : 13 | return os.path.join(FLOORPLANS_DIR, f"{scene_id}_floor_trav_no_obj_0.png") 14 | 15 | 16 | # generate grid 17 | class FloorPlanEnv(MiniBehaviorEnv): 18 | def __init__(self, 19 | img_path=None, 20 | mode='cartesian', 21 | scene_id='beechwood_0_int', 22 | num_objs=None, 23 | max_steps=1e5, 24 | ): 25 | 26 | self.scene_id = scene_id 27 | img_path = get_floorplan(scene_id) 28 | self.img_path = img_path 29 | self.floor_plan = img_to_array(img_path) # assume img_path is to grid version of floorplan 30 | 31 | if num_objs is None: 32 | num_objs = {'goal': 1} 33 | 34 | self.height, self.width = np.shape(self.floor_plan) 35 | self.num_objs = num_objs 36 | self.mission = '' 37 | 38 | super().__init__(mode=mode, 39 | width=self.width, 40 | height=self.height, 41 | num_objs=self.num_objs, 42 | max_steps=max_steps) 43 | 44 | 45 | def add_walls(self): 46 | # add walls based on floor plan 47 | for i in range(self.height): 48 | for j in range(self.width): 49 | if self.floor_plan[i, j] == 0: 50 | self.put_obj(Wall(), j, i) 51 | 52 | def _gen_grid(self, width, height): 53 | self.grid = BehaviorGrid(width, height) 54 | self.add_walls() 55 | self._gen_objs() 56 | assert self._init_conditions(), "Does not satisfy initial conditions" 57 | self.place_agent() 58 | 59 | def _gen_objs(self): 60 | goal = self.objs['goal'][0] 61 | self.target_pos = self.place_obj(goal) 62 | 63 | def _end_conditions(self): 64 | pass 65 | # if np.all(self.agent_pos == self.target_pos): 66 | # return True 67 | # else: 68 | # return False 69 | 70 | 71 | # register environments of all floorplans in floorplans dir 72 | all_scenes = os.listdir(FLOORPLANS_DIR) 73 | 74 | for img in all_scenes: 75 | img_name = img 76 | if '/' in img_name: 77 | img_name = img_name.split('/')[1] 78 | if '.' in img_name: 79 | img_name = img_name.split('.')[0] 80 | env_id = 'MiniGrid-{}-0x0-N1-v0'.format(img_name) 81 | 82 | register( 83 | id=env_id, 84 | entry_point='mini_behavior.envs:FloorPlanEnv', 85 | kwargs={'img_path': '{}/{}'.format(FLOORPLANS_DIR, img)} 86 | ) 87 | -------------------------------------------------------------------------------- /mini_behavior/floorplans/beechwood_0_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/floorplans/beechwood_0_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/floorplans/beechwood_1_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/floorplans/beechwood_1_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/floorplans/benevolence_0_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/floorplans/benevolence_0_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/floorplans/benevolence_1_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/floorplans/benevolence_1_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/floorplans/benevolence_2_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/floorplans/benevolence_2_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/floorplans/ihlen_0_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/floorplans/ihlen_0_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/floorplans/ihlen_1_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/floorplans/ihlen_1_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/floorplans/init_install_printer.json: -------------------------------------------------------------------------------- 1 | { 2 | "Grid": 3 | { 4 | "mission": "install a printer", 5 | "auto": { 6 | "room_split_dirs": ["vert", "horz"], 7 | "min_room_dim": 1, 8 | "max_num_room": 4 9 | }, 10 | "width": 12, 11 | "height": 12, 12 | "agents": 13 | { 14 | "pos": null, 15 | "dir": null 16 | }, 17 | "rooms": 18 | { 19 | "num": 2, 20 | "initial": 21 | [ 22 | { 23 | "top": [1, 1], 24 | "size": [5, 10], 25 | "furnitures": 26 | { 27 | "num": 2, 28 | "initial": 29 | [ 30 | { 31 | "type": "printer", 32 | "state": [["toggleable", 0]], 33 | "pos": [2, 2], 34 | "objs": null 35 | }, 36 | { 37 | "type": "table", 38 | "state": null, 39 | "pos": null, 40 | "objs": { 41 | "num": 1, 42 | "initial": 43 | [ 44 | { 45 | "type": "book", 46 | "state": [["dustyable", 1]], 47 | "pos": null 48 | } 49 | ] 50 | } 51 | } 52 | ] 53 | } 54 | }, 55 | { 56 | "top": [7, 1], 57 | "size": [4, 10], 58 | "furnitures": 59 | { 60 | "num": 2, 61 | "initial": 62 | [ 63 | { 64 | "type": "printer", 65 | "state": [["toggleable", 0]], 66 | "pos": null, 67 | "objs": null 68 | }, 69 | { 70 | "type": "box", 71 | "state": null, 72 | "pos": null, 73 | "objs": null 74 | } 75 | ] 76 | } 77 | } 78 | ] 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /mini_behavior/floorplans/merom_0_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/floorplans/merom_0_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/floorplans/merom_1_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/floorplans/merom_1_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/floorplans/pomaria_0_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/floorplans/pomaria_0_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/floorplans/pomaria_1_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/floorplans/pomaria_1_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/floorplans/pomaria_2_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/floorplans/pomaria_2_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/floorplans/rs_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/floorplans/rs_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/floorplans/wainscott_0_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/floorplans/wainscott_0_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/floorplans/wainscott_1_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/floorplans/wainscott_1_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/objects.py: -------------------------------------------------------------------------------- 1 | from .rendering import * 2 | from mini_bddl import OBJECT_TO_IDX 3 | from .utils.globals import COLOR_TO_IDX, COLORS 4 | from .utils.objects_base import WorldObj, FurnitureObj 5 | 6 | 7 | class Goal(WorldObj): 8 | def __init__(self, color='green', name='goal'): 9 | super().__init__('goal', color=color, name=name, can_overlap=True) 10 | 11 | def render(self, img): 12 | fill_coords(img, point_in_rect(0, 1, 0, 1), COLORS[self.color]) 13 | 14 | 15 | class Ashcan(FurnitureObj): 16 | def __init__(self, width=1, height=1, color='blue', name='ashcan'): 17 | super(Ashcan, self).__init__('ashcan', width, height, {0, 1, 2}, color, name, can_contain={0, 1, 2}) 18 | 19 | 20 | class Bed(FurnitureObj): 21 | def __init__(self, width=3, height=2, color='purple', name='bed'): 22 | super(Bed, self).__init__('bed', width, height, {0}, color, name, can_overlap=True) 23 | 24 | 25 | class Bin(FurnitureObj): 26 | def __init__(self, width=1, height=1, color='purple', name='bin'): 27 | super(Bin, self).__init__('bin', width, height, {0, 1, 2}, color, name, can_contain={0, 1, 2}) 28 | 29 | 30 | class Box(FurnitureObj): 31 | def __init__(self, width=2, height=2, color='tan', name='box'): 32 | super(Box, self).__init__('box', width, height, {0}, color, name, can_contain={0}) 33 | 34 | 35 | class Bucket(FurnitureObj): 36 | def __init__(self, width=1, height=2, color='l_blue', name='bucket'): 37 | super(Bucket, self).__init__('bucket', width, height, {0}, color, name, can_contain={0}) 38 | 39 | 40 | class Cabinet(FurnitureObj): 41 | def __init__(self, width=2, height=3, color='brown', name='cabinet'): 42 | super(Cabinet, self).__init__('cabinet', width, height, {0, 1, 2}, color, name, can_contain={0, 1, 2}, can_seebehind=False) 43 | 44 | 45 | class Car(FurnitureObj): 46 | def __init__(self, width=3, height=2, color='blue', name='car'): 47 | super(Car, self).__init__('car', width, height, {0, 1}, color, name, can_contain={0}) 48 | 49 | 50 | class Chair(FurnitureObj): 51 | def __init__(self, width=1, height=1, color='brown', name='chair'): 52 | super(Chair, self).__init__('chair', width, height, {0, 1}, color, name) 53 | 54 | 55 | class Countertop(FurnitureObj): 56 | def __init__(self, width=3, height=2, color='tan', name='countertop'): 57 | super(Countertop, self).__init__('countertop', width, height, {0}, color, name, can_seebehind=True) 58 | 59 | 60 | class Door(FurnitureObj): 61 | def __init__(self, dir=None, width=1, height=1, color='yellow', is_open=False, name='door'): 62 | self.is_open = is_open 63 | self.dir = dir 64 | super().__init__('door', width, height, { 65 | 0, 1, 2}, color, name, can_overlap=is_open, can_seebehind=is_open) 66 | 67 | def update(self, env): 68 | self.is_open = self.states['openable'].get_value(env) 69 | self.can_overlap = self.is_open 70 | self.can_seebehind = self.is_open 71 | 72 | def encode(self): 73 | """Encode the a description of this object as a seed 10_3-tuple of integers""" 74 | 75 | # State, 0: open, seed 0_2: closed, seed 0_2: locked 76 | if self.is_open: 77 | state = 0 78 | # elif self.is_locked: 79 | # state = 2 80 | else: 81 | state = 1 82 | 83 | return OBJECT_TO_IDX[self.type], COLOR_TO_IDX[self.color], state 84 | 85 | def get_state(self): 86 | if self.is_open: 87 | return True 88 | else: 89 | return False 90 | 91 | def render(self, img): 92 | c = COLORS[self.color] 93 | 94 | if self.is_open: 95 | fill_coords(img, point_in_rect(0.88, 1.00, 0.00, 1.00), c) 96 | fill_coords(img, point_in_rect(0.92, 0.96, 0.04, 0.96), (0, 0, 0)) 97 | return 98 | 99 | # Door frame and door 100 | fill_coords(img, point_in_rect(0.00, 1.00, 0.00, 1.00), c) 101 | fill_coords(img, point_in_rect(0.04, 0.96, 0.04, 0.96), (0, 0, 0)) 102 | fill_coords(img, point_in_rect(0.08, 0.92, 0.08, 0.92), c) 103 | fill_coords(img, point_in_rect(0.12, 0.88, 0.12, 0.88), (0, 0, 0)) 104 | 105 | # Draw door handle 106 | fill_coords(img, point_in_circle(cx=0.75, cy=0.50, r=0.08), c) 107 | 108 | 109 | class ElectricRefrigerator(FurnitureObj): 110 | def __init__(self, width=2, height=3, color='l_blue', name='electric_refrigerator'): 111 | super(ElectricRefrigerator, self).__init__('electric_refrigerator', width, height, {0, 1, 2}, color, name, can_contain={0, 1, 2}, can_seebehind=False) 112 | 113 | 114 | # TODO: add wall to object properties 115 | class Wall(FurnitureObj): 116 | def __init__(self, color='grey'): 117 | super().__init__('wall', 1, 1, {0, 1, 2}, color, 'wall', can_seebehind=False) 118 | 119 | def render(self, img): 120 | fill_coords(img, point_in_rect(0, 1, 0, 1), COLORS['grey']) 121 | 122 | 123 | class Shelf(FurnitureObj): 124 | def __init__(self, width=2, height=3, color='brown', name='shelf'): 125 | super(Shelf, self).__init__('shelf', width, height, {0, 1}, color, name, can_contain={0, 1}, can_seebehind=False) 126 | 127 | 128 | class Shower(FurnitureObj): 129 | def __init__(self, width=3, height=2, color='l_blue', name='shower'): 130 | super(Shower, self).__init__('shower', width, height, {0, 1, 2}, color, name) 131 | 132 | 133 | class Sink(FurnitureObj): 134 | def __init__(self, width=2, height=2, color='blue', name='sink'): 135 | super(Sink, self).__init__('sink', width, height, {0}, color, name, can_contain={0}, can_overlap=False, can_seebehind=True) 136 | 137 | 138 | class Sofa(FurnitureObj): 139 | def __init__(self, width=3, height=2, color='red', name='sofa'): 140 | super(Sofa, self).__init__('sofa', width, height, {0}, color, name) 141 | 142 | 143 | class Stove(FurnitureObj): 144 | def __init__(self, width=3, height=2, color='grey', name='stove'): 145 | super(Stove, self).__init__('stove', width, height, {0, 1}, color, name, can_contain={0}) 146 | 147 | 148 | class Table(FurnitureObj): 149 | def __init__(self, width=3, height=2, color='tan', name='table'): 150 | super(Table, self).__init__('table', width, height, {1}, color, name) 151 | 152 | 153 | OBJECT_CLASS = { 154 | 'ashcan': Ashcan, 155 | 'bed': Bed, 156 | 'bin': Bin, 157 | 'box': Box, 158 | 'bucket': Bucket, 159 | 'cabinet': Cabinet, 160 | 'chair': Chair, 161 | 'car': Car, 162 | 'countertop': Countertop, 163 | 'door': Door, 164 | 'electric_refrigerator': ElectricRefrigerator, 165 | 'wall': Wall, 166 | 'shelf': Shelf, 167 | 'shower': Shower, 168 | 'sink': Sink, 169 | 'sofa': Sofa, 170 | 'stove': Stove, 171 | 'table': Table 172 | } 173 | -------------------------------------------------------------------------------- /mini_behavior/register.py: -------------------------------------------------------------------------------- 1 | # FROM MINIGRID REPO 2 | 3 | from gym.envs.registration import register as gym_register 4 | 5 | env_list = [] 6 | 7 | 8 | def register( 9 | id, 10 | entry_point, 11 | reward_threshold=0.95, 12 | kwargs=None 13 | ): 14 | assert id.startswith("MiniGrid-") 15 | assert id not in env_list 16 | 17 | # Register the environment with OpenAI gym 18 | gym_register( 19 | id=id, 20 | entry_point=entry_point, 21 | reward_threshold=reward_threshold, 22 | kwargs=kwargs, 23 | ) 24 | 25 | # Add the environment to the set 26 | env_list.append(id) 27 | -------------------------------------------------------------------------------- /mini_behavior/rendering.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | from gym_minigrid.rendering import * 3 | 4 | 5 | def img_to_array(img_path): 6 | """ 7 | given a path to image, return array 8 | """ 9 | img = Image.open(img_path) 10 | array = np.asarray(img) 11 | return array 12 | 13 | 14 | def point_in_icon(img, img_array): 15 | def fn(x, y): 16 | x = x * img.shape[1] - 0.5 17 | y = y * img.shape[0] - 0.5 18 | x = int(x / np.shape(img)[1] * np.shape(img_array)[1]) 19 | y = int(y / np.shape(img)[0] * np.shape(img_array)[0]) 20 | 21 | return np.all(img_array[y, x] != 255) 22 | 23 | return fn 24 | -------------------------------------------------------------------------------- /mini_behavior/scenes/beechwood_0_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/scenes/beechwood_0_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/scenes/beechwood_1_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/scenes/beechwood_1_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/scenes/benevolence_0_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/scenes/benevolence_0_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/scenes/benevolence_1_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/scenes/benevolence_1_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/scenes/benevolence_2_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/scenes/benevolence_2_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/scenes/ihlen_0_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/scenes/ihlen_0_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/scenes/ihlen_1_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/scenes/ihlen_1_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/scenes/merom_0_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/scenes/merom_0_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/scenes/merom_1_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/scenes/merom_1_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/scenes/pomaria_0_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/scenes/pomaria_0_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/scenes/pomaria_1_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/scenes/pomaria_1_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/scenes/pomaria_2_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/scenes/pomaria_2_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/scenes/rs_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/scenes/rs_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/scenes/wainscott_0_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/scenes/wainscott_0_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/scenes/wainscott_1_int_floor_trav_no_obj_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/scenes/wainscott_1_int_floor_trav_no_obj_0.png -------------------------------------------------------------------------------- /mini_behavior/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/__init__.py -------------------------------------------------------------------------------- /mini_behavior/utils/get_icon_square.py: -------------------------------------------------------------------------------- 1 | import os 2 | from PIL import Image 3 | from mini_behavior.mini_behavior.rendering import img_to_array 4 | import numpy as np 5 | 6 | 7 | def square_img_array(img_path): 8 | img_array = img_to_array(img_path) 9 | 10 | # 0 = black, 255 = white 11 | num_dims = np.ndim(img_array) 12 | array = img_array[:, :] 13 | 14 | height, width = np.shape(array) 15 | start_row, start_col = 0, 0 16 | end_row, end_col = height - 1, width - 1 17 | 18 | while np.all(array[start_row, :] == 255): 19 | start_row += 1 20 | 21 | while np.all(array[end_row, :] == 255): 22 | end_row -= 1 23 | 24 | while np.all(array[:, start_col] == 255): 25 | start_col += 1 26 | 27 | while np.all(array[:, end_col] == 255): 28 | end_col -= 1 29 | 30 | assert start_row <= end_row, 'incorrect start/end row' 31 | assert start_col <= end_col, 'incorrect start/end col' 32 | 33 | new_size = max(end_row - start_row, end_col - start_col) 34 | start = int((height - new_size) / 2) 35 | end = int((height + new_size) / 2) 36 | 37 | square = img_array[start: end, start: end] 38 | 39 | return square 40 | 41 | 42 | # dir with all icon images 43 | # img_dir = '/Users/emilyjin/Downloads/icons' 44 | img_dir = '/Users/emilyjin/Downloads/untitled folder' 45 | # dir to save cropped icons as square 46 | crop_dir = '/mini_behavior/mini_behavior/utils/state_icons' 47 | 48 | imgs = os.listdir(img_dir) 49 | for img in imgs: 50 | if img[0] == '.': 51 | continue 52 | print(img) 53 | img_path = os.path.join(img_dir, img) 54 | square = square_img_array(img_path) 55 | square_img = Image.fromarray(square) 56 | # square_img.show() 57 | save_path = os.path.join(crop_dir, img) 58 | square_img.save(img) 59 | -------------------------------------------------------------------------------- /mini_behavior/utils/globals.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | # Map of color names to RGB values 4 | COLORS = { 5 | 'red' : np.array([128, 0, 32]), 6 | 'green' : np.array([0, 255, 0]), 7 | 'blue' : np.array([0, 0, 255]), 8 | 'purple': np.array([112, 39, 195]), 9 | 'yellow': np.array([255, 255, 0]), 10 | 'grey' : np.array([100, 100, 100]), 11 | 'orange': np.array([255, 165, 0]), 12 | 'white' : np.array([255, 255, 255]), 13 | 'l_green': np.array([46, 139, 87]), 14 | 'brown': np.array([101, 67, 33]), 15 | 'pink': np.array([255, 192, 203]), 16 | 'l_blue': np.array([48, 132, 158]), 17 | 'tan': np.array([176, 142, 103]), 18 | 'black': np.array([0, 0, 0]) 19 | } 20 | 21 | COLOR_NAMES = sorted(list(COLORS.keys())) 22 | 23 | # Used to map colors to integers 24 | COLOR_TO_IDX = { 25 | 'red': 0, 26 | 'green': 1, 27 | 'blue': 2, 28 | 'purple': 3, 29 | 'yellow': 4, 30 | 'grey': 5, 31 | 'orange': 6, 32 | 'white': 7, 33 | 'l_green': 8, 34 | 'brown': 9, 35 | 'pink': 10, 36 | 'l_blue': 11, 37 | 'tan': 12, 38 | 'black': 13 39 | } 40 | 41 | IDX_TO_COLOR = dict(zip(COLOR_TO_IDX.values(), COLOR_TO_IDX.keys())) 42 | 43 | # Map of agent direction indices to vectors 44 | DIR_TO_VEC = [ 45 | # Pointing right (positive X) 46 | np.array((1, 0)), 47 | # Down (positive Y) 48 | np.array((0, 1)), 49 | # Pointing left (negative X) 50 | np.array((-1, 0)), 51 | # Up (negative Y) 52 | np.array((0, -1)), 53 | ] 54 | -------------------------------------------------------------------------------- /mini_behavior/utils/load.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | 4 | 5 | def load_json(filename): 6 | path = os.path.abspath(filename) 7 | with open(path, 'r') as f: 8 | return json.load(f) 9 | -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/apple.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/apple.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/ashcan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/ashcan.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/backpack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/backpack.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/ball.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/ball.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/banana.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/banana.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/basket.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/basket.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/bed.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/bed.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/beef.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/beef.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/bin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/bin.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/blender.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/blender.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/book.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/book.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/bow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/bow.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/box.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/box.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/bread.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/bread.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/broom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/broom.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/bucket.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/bucket.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/cabinet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/cabinet.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/cake.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/cake.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/calculator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/calculator.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/candle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/candle.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/candy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/candy.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/car.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/car.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/carton.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/carton.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/carving_knife.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/carving_knife.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/casserole.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/casserole.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/chair.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/chair.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/chicken.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/chicken.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/chip.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/chip.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/cleaning_brush.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/cleaning_brush.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/cookie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/cookie.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/countertop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/countertop.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/date.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/date.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/document.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/document.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/dustpan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/dustpan.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/egg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/egg.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/electric_refrigerator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/electric_refrigerator.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/fish.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/fish.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/folder.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/folder.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/fork.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/fork.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/gym_shoe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/gym_shoe.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/hamburger.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/hamburger.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/hammer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/hammer.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/hardback.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/hardback.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/hardcover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/hardcover.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/jar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/jar.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/jewelry.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/jewelry.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/juice.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/juice.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/kettle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/kettle.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/knife.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/knife.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/lemon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/lemon.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/lettuce.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/lettuce.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/marker.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/marker.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/necklace.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/necklace.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/notebook.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/notebook.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/oatmeal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/oatmeal.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/olive.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/olive.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/package.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/package.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/pan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/pan.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/pen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/pen.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/pencil.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/pencil.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/plate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/plate.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/plywood.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/plywood.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/pop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/pop.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/pot_plant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/pot_plant.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/printer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/printer.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/radish.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/radish.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/rag.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/rag.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/salad.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/salad.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/sandwich.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/sandwich.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/saw.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/saw.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/scrub_brush.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/scrub_brush.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/shelf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/shelf.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/shoe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/shoe.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/shower.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/shower.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/sink.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/sink.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/soap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/soap.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/sock.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/sock.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/sofa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/sofa.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/soup.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/soup.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/spoon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/spoon.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/stove.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/stove.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/strawberry.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/strawberry.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/sugar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/sugar.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/table.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/table.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/tea_bag.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/tea_bag.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/teapot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/teapot.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/toilet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/toilet.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/tomato.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/tomato.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/towel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/towel.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/trash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/trash.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/vegetable_oil.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/vegetable_oil.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/water.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/water.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_icons/window.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/object_icons/window.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/object_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "apple": [ 3 | "cookable", 4 | "freezable", 5 | "sliceable" 6 | ], 7 | "ashcan": [ 8 | "dustyable", 9 | "stainable" 10 | ], 11 | "ball": [ 12 | "dustyable", 13 | "stainable" 14 | ], 15 | "banana": [ 16 | "cookable", 17 | "dustyable", 18 | "freezable", 19 | "stainable" 20 | ], 21 | "basket": [ 22 | "dustyable", 23 | "stainable" 24 | ], 25 | "bed": [ 26 | "dustyable", 27 | "stainable" 28 | ], 29 | "beef": [ 30 | "cookable", 31 | "freezable" 32 | ], 33 | "bin": [ 34 | "dustyable", 35 | "stainable" 36 | ], 37 | "blender": [ 38 | "dustyable", 39 | "stainable", 40 | "toggleable" 41 | ], 42 | "book": [ 43 | "dustyable" 44 | ], 45 | "bow": [ 46 | "dustyable" 47 | ], 48 | "box": [ 49 | "dustyable" 50 | ], 51 | "bread": [ 52 | "cookable", 53 | "freezable" 54 | ], 55 | "broom": [ 56 | "cleaningTool", 57 | "dustyable" 58 | ], 59 | "bucket": [ 60 | "dustyable", 61 | "stainable" 62 | ], 63 | "cabinet": [ 64 | "dustyable", 65 | "openable", 66 | "stainable" 67 | ], 68 | "cake": [ 69 | "cookable", 70 | "freezable" 71 | ], 72 | "calculator": [ 73 | "dustyable", 74 | "toggleable" 75 | ], 76 | "candy": [ 77 | "cookable" 78 | ], 79 | "candle": [ 80 | "dustyable" 81 | ], 82 | "car": [ 83 | "dustyable", 84 | "openable", 85 | "stainable" 86 | ], 87 | "carton": [ 88 | "dustyable" 89 | ], 90 | "carving_knife": [ 91 | "dustyable", 92 | "slicer", 93 | "stainable" 94 | ], 95 | "casserole": [ 96 | "cookable", 97 | "freezable", 98 | "stainable" 99 | ], 100 | "chair": [ 101 | "dustyable", 102 | "stainable" 103 | ], 104 | "chicken": [ 105 | "cookable", 106 | "freezable" 107 | ], 108 | "chip": [ 109 | "cookable" 110 | ], 111 | "cookie": [ 112 | "cookable", 113 | "freezable" 114 | ], 115 | "countertop": [ 116 | "dustyable", 117 | "stainable" 118 | ], 119 | "date": [ 120 | "cookable", 121 | "freezable" 122 | ], 123 | "document": [ 124 | "dustyable" 125 | ], 126 | "door": [ 127 | "dustyable", 128 | "openable", 129 | "stainable" 130 | ], 131 | "dustpan": [ 132 | "dustyable", 133 | "stainable" 134 | ], 135 | "egg": [ 136 | "cookable", 137 | "freezable" 138 | ], 139 | "electric_refrigerator": [ 140 | "coldSource", 141 | "dustyable", 142 | "openable", 143 | "stainable" 144 | ], 145 | "fish": [ 146 | "cookable", 147 | "freezable" 148 | ], 149 | "floor": [ 150 | "dustyable", 151 | "stainable" 152 | ], 153 | "folder": [ 154 | "dustyable" 155 | ], 156 | "fork": [ 157 | "dustyable", 158 | "stainable" 159 | ], 160 | "gym_shoe": [ 161 | "dustyable", 162 | "stainable" 163 | ], 164 | "hardback": [ 165 | "dustyable" 166 | ], 167 | "hamburger": [ 168 | "cookable", 169 | "freezable" 170 | ], 171 | "hammer": [ 172 | "dustyable", 173 | "stainable" 174 | ], 175 | "highlighter": [ 176 | "dustyable", 177 | "stainable" 178 | ], 179 | "jewelry": [ 180 | "dustyable", 181 | "stainable" 182 | ], 183 | "juice": [ 184 | "freezable" 185 | ], 186 | "kettle": [ 187 | "dustyable", 188 | "stainable" 189 | ], 190 | "knife": [ 191 | "dustyable", 192 | "slicer", 193 | "stainable" 194 | ], 195 | "lemon": [ 196 | "cookable", 197 | "freezable", 198 | "sliceable" 199 | ], 200 | "lettuce": [ 201 | "freezable" 202 | ], 203 | "marker": [ 204 | "dustyable", 205 | "stainable" 206 | ], 207 | "necklace": [ 208 | "dustyable", 209 | "stainable" 210 | ], 211 | "notebook": [ 212 | "dustyable" 213 | ], 214 | "oatmeal": [ 215 | "cookable", 216 | "freezable" 217 | ], 218 | "olive": [ 219 | "cookable", 220 | "freezable" 221 | ], 222 | "package": [ 223 | "dustyable", 224 | "openable" 225 | ], 226 | "pan": [ 227 | "dustyable", 228 | "stainable" 229 | ], 230 | "pen": [ 231 | "dustyable", 232 | "stainable" 233 | ], 234 | "pencil": [ 235 | "dustyable", 236 | "stainable" 237 | ], 238 | "plate": [ 239 | "dustyable", 240 | "stainable" 241 | ], 242 | "plywood": [ 243 | "dustyable", 244 | "stainable" 245 | ], 246 | "pop": [ 247 | "freezable" 248 | ], 249 | "pot_plant": [ 250 | "soakable" 251 | ], 252 | "printer": [ 253 | "dustyable", 254 | "toggleable" 255 | ], 256 | "radish": [ 257 | "cookable", 258 | "freezable", 259 | "stainable" 260 | ], 261 | "rag": [ 262 | "cleaningTool", 263 | "soakable", 264 | "stainable" 265 | ], 266 | "salad": [ 267 | "cookable", 268 | "freezable" 269 | ], 270 | "sandwich": [ 271 | "cookable", 272 | "freezable" 273 | ], 274 | "saw": [ 275 | "dustyable", 276 | "stainable" 277 | ], 278 | "scrub_brush": [ 279 | "cleaningTool", 280 | "dustyable", 281 | "soakable", 282 | "stainable" 283 | ], 284 | "shelf": [ 285 | "dustyable", 286 | "stainable" 287 | ], 288 | "shoe": [ 289 | "dustyable", 290 | "stainable" 291 | ], 292 | "shower": [ 293 | "stainable" 294 | ], 295 | "sink": [ 296 | "dustyable", 297 | "stainable", 298 | "toggleable" 299 | ], 300 | "soap": [], 301 | "sock": [ 302 | "dustyable", 303 | "stainable" 304 | ], 305 | "sofa": [ 306 | "dustyable", 307 | "stainable" 308 | ], 309 | "soup": [ 310 | "cookable", 311 | "freezable" 312 | ], 313 | "spoon": [ 314 | "dustyable", 315 | "stainable" 316 | ], 317 | "stove": [ 318 | "dustyable", 319 | "heatSource", 320 | "openable", 321 | "stainable", 322 | "toggleable" 323 | ], 324 | "strawberry": [ 325 | "cookable", 326 | "freezable", 327 | "sliceable" 328 | ], 329 | "sugar": [ 330 | "cookable" 331 | ], 332 | "table": [ 333 | "dustyable", 334 | "stainable" 335 | ], 336 | "tea_bag": [ 337 | "dustyable", 338 | "soakable", 339 | "stainable" 340 | ], 341 | "teapot": [ 342 | "dustyable", 343 | "stainable" 344 | ], 345 | "toilet": [ 346 | "dustyable", 347 | "stainable" 348 | ], 349 | "tomato": [ 350 | "cookable", 351 | "freezable", 352 | "sliceable" 353 | ], 354 | "towel": [ 355 | "cleaningTool", 356 | "soakable", 357 | "stainable" 358 | ], 359 | "vegetable_oil": [ 360 | "cookable", 361 | "freezable" 362 | ], 363 | "water": [ 364 | "freezable" 365 | ], 366 | "window": [ 367 | "dustyable", 368 | "openable", 369 | "stainable" 370 | ] 371 | } -------------------------------------------------------------------------------- /mini_behavior/utils/save.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pickle as pkl 3 | 4 | 5 | def all_cur_pos(env): 6 | """ 7 | returns dict with key=obj, value=cur_pos 8 | """ 9 | pos = {'agent': [int(obj_pos) for obj_pos in env.agent.cur_pos]} 10 | 11 | for obj_name in env.obj_instances: 12 | obj_instance = env.obj_instances[obj_name] 13 | pos[obj_name] = [int(obj_pos) for obj_pos in obj_instance.cur_pos] 14 | 15 | return pos 16 | 17 | 18 | def all_state_values(env): 19 | """ 20 | returns dict with key=obj_state, value=state value 21 | """ 22 | states = {} 23 | for obj_name, obj_instance in env.obj_instances.items(): 24 | obj_states = obj_instance.get_all_state_values(env) 25 | states.update(obj_states) 26 | return states 27 | 28 | 29 | # save last action, all states, all obj pos, all door pos 30 | def get_step(env): 31 | step_count = env.step_count 32 | action = 'none' if env.last_action is None else env.last_action.name 33 | state = env.get_state() 34 | state_values = all_state_values(env) 35 | 36 | # door_pos = [] 37 | # for door in env.doors: 38 | # door_pos.append(door.cur_pos) 39 | step = {'action': action, 40 | 'predicates': state_values, 41 | 'grid': state['grid'], 42 | 'agent_dir': state['agent']['dir'], 43 | 'agent_pos': state['agent']['cur_pos'] 44 | # 'door_pos': door_pos 45 | } 46 | 47 | return step_count, step 48 | 49 | 50 | # save demo_16 as a pkl file 51 | def save_demo(all_steps, env_name, episode): 52 | demo_dir = os.path.join('./demos', env_name) 53 | if not os.path.isdir(demo_dir): 54 | os.makedirs(demo_dir) 55 | all_files = os.listdir(demo_dir) 56 | demo_num = len(all_files) 57 | demo_file = os.path.join(demo_dir, '{}_{}'.format(env_name, demo_num)) 58 | assert not os.path.isfile(demo_file) 59 | 60 | print('saving demo to: {}'.format(demo_file)) 61 | 62 | with open(demo_file, 'wb') as f: 63 | pkl.dump(all_steps, f) 64 | 65 | print('saved') 66 | 67 | 68 | # save demo_16 as a pkl file 69 | def save_snapshots(env_steps, model_name='', date=''): 70 | dir = '../snapshots' 71 | if not os.path.isdir(dir): 72 | os.mkdir(dir) 73 | snapshot_file = os.path.join(dir, f'{model_name}_{date}') 74 | 75 | print('saving snapshot to: {}'.format(snapshot_file)) 76 | 77 | # hf = h5py.File('{demo_file}.h5', 'w') 78 | 79 | with open(snapshot_file, 'wb') as f: 80 | pkl.dump(env_steps, f) 81 | 82 | print('saved') 83 | 84 | 85 | def open_demo(demo_file): 86 | assert os.path.isfile(demo_file) 87 | 88 | with open(demo_file, 'rb') as f: 89 | demo = pkl.load(f) 90 | print('num_steps in demo_16: {}'.format(len(demo))) 91 | return demo 92 | 93 | 94 | def get_step_num(step_num, demo_file): 95 | # returns dict with keys: action, grid, agent_carrying, agent_pos 96 | demo = open_demo(demo_file) 97 | return demo[step_num] 98 | 99 | 100 | def get_action_num(step_num, demo_file): 101 | demo = open_demo(demo_file) 102 | action = demo[step_num]['action'] 103 | print('action at step {}: {}'.format(step_num, action.name)) 104 | return action 105 | 106 | 107 | def get_states(step_num, demo_file): 108 | demo = open_demo(demo_file) 109 | states = demo[step_num]['states'] 110 | return states 111 | 112 | 113 | def print_actions_states(demo_file): 114 | demo = open_demo(demo_file) 115 | for step_num in demo: 116 | print('{}: {}'.format(step_num, demo[step_num]['action'])) 117 | print('true predicates') 118 | for state in demo[step_num]['predicates']: 119 | if demo[step_num]['predicates'][state]: 120 | print(state) 121 | 122 | 123 | def print_actions(demo_file): 124 | demo = open_demo(demo_file) 125 | for step_num in demo: 126 | print('{}: {}'.format(step_num, demo[step_num]['action'])) 127 | 128 | 129 | # demo_file = '/Users/emilyjin/Code/behavior/demos/MiniGrid-ThrowLeftoversFourRooms-8x8-N2-v1/2/MiniGrid-ThrowLeftoversFourRooms-8x8-N2-v1_10' 130 | # print_actions_states(demo_file) 131 | -------------------------------------------------------------------------------- /mini_behavior/utils/scene_to_grid.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | import numpy as np 3 | import math 4 | import os 5 | 6 | FLOORPLANS_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "floorplans") 7 | 8 | def img_to_array(img_path): 9 | img = Image.open(img_path) 10 | array = np.asarray(img) 11 | return array 12 | 13 | def get_floorplan(scene_id) : 14 | return os.path.join(FLOORPLANS_DIR, f"{scene_id}_floor_trav_no_obj_0.png") 15 | 16 | def crop_img(img_array): 17 | # 0 = black, 255 = white 18 | height, width = np.shape(img_array) 19 | start_row = 0 20 | end_row = height - 1 21 | start_col = 0 22 | end_col = width - 1 23 | 24 | while np.all(img_array[start_row, :] == 0): 25 | start_row += 1 26 | 27 | while np.all(img_array[end_row, :] == 0): 28 | end_row -= 1 29 | 30 | while np.all(img_array[:, start_col] == 0): 31 | start_col += 1 32 | 33 | while np.all(img_array[:, end_col] == 0): 34 | end_col -= 1 35 | 36 | assert start_row <= end_row, 'incorrect start/end row' 37 | assert start_col <= end_col, 'incorrect start/end col' 38 | 39 | return img_array[start_row: end_row, start_col: end_col] 40 | 41 | 42 | def get_pix_per_grid(img_array): 43 | # get pixels per grid 44 | def iter_rows(array, cur_min=math.inf): 45 | for row in array: 46 | count = 0 47 | for i in range(np.shape(array)[1]): 48 | if row[i] == 0: 49 | count += 1 50 | else: 51 | if count != 0: 52 | cur_min = max(min(cur_min, count), 8) 53 | count = 0 54 | return cur_min 55 | 56 | pix_per_grid = iter_rows(img_array) 57 | pix_per_grid = iter_rows(np.transpose(img_array), pix_per_grid) 58 | 59 | return pix_per_grid 60 | 61 | 62 | def gen_grid_from_array(img_array): 63 | pix_per_grid = get_pix_per_grid(img_array) 64 | 65 | height, width = np.shape(img_array) 66 | grid_rows = math.ceil(height / pix_per_grid) 67 | grid_cols = math.ceil(width / pix_per_grid) 68 | 69 | # create grid with outer layer of walls 70 | grid = np.zeros((grid_rows + 2, grid_cols + 2)) 71 | grid[0, :] = 0 72 | grid[-1, :] = 0 73 | grid[:, 0] = 0 74 | grid[:, -1] = 0 75 | 76 | # convert img to grid 77 | for i in range(grid_rows): 78 | for j in range(grid_cols): 79 | start_row = i * pix_per_grid 80 | end_row = (i+1) * pix_per_grid if (i+1) * pix_per_grid <= height else height 81 | start_col = j * pix_per_grid 82 | end_col = (j + 1) * pix_per_grid if (j+1) * pix_per_grid <= width else width 83 | 84 | sub_img = img_array[start_row: end_row, start_col: end_col] 85 | num_black = sub_img[np.where(sub_img == 0)].size 86 | num_white = sub_img[np.where(sub_img == 255)].size 87 | 88 | # set grid color to majority color in the subimg 89 | if num_black > num_white: 90 | grid[i + 1, j + 1] = 0 91 | else: 92 | grid[i + 1, j + 1] = 255 93 | 94 | return grid 95 | 96 | 97 | def gen_grid_from_img(img='rs_int_floor_trav_no_obj_0.png', img_dir='scenes', save_dir='floorplans'): 98 | # load and process img into grid 99 | img_path = os.path.join(img_dir, img) 100 | img_array = img_to_array(img_path) 101 | img_array = crop_img(img_array) 102 | grid = gen_grid_from_array(img_array) 103 | 104 | # show grid 105 | grid = grid.astype(np.uint8) 106 | grid_img = Image.fromarray(grid) 107 | grid_img.show() 108 | 109 | # save grid in save_dir 110 | save_path = os.path.join(save_dir, img) 111 | print('saving grid to: {}'.format(save_path)) 112 | grid_img.save(save_path) 113 | 114 | return grid 115 | -------------------------------------------------------------------------------- /mini_behavior/utils/state_icons/cookable.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/state_icons/cookable.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/state_icons/dustyable.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/state_icons/dustyable.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/state_icons/freezable.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/state_icons/freezable.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/state_icons/openable.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/state_icons/openable.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/state_icons/sliceable.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/state_icons/sliceable.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/state_icons/soakable.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/state_icons/soakable.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/state_icons/stainable.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/state_icons/stainable.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/state_icons/toggleable.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StanfordVL/mini_behavior/37cbc3f9e92fba23baae32fae7b8295df2331945/mini_behavior/utils/state_icons/toggleable.jpg -------------------------------------------------------------------------------- /mini_behavior/utils/states_base.py: -------------------------------------------------------------------------------- 1 | # MODIFIED FROM IGIBSON REPO 2 | 3 | import os 4 | from abc import abstractmethod 5 | from mini_behavior.rendering import * 6 | 7 | class BaseObjectState: 8 | """ 9 | Base ObjectState class. Do NOT inherit from this class directly - use either AbsoluteObjectState or 10 | RelativeObjectState. 11 | """ 12 | 13 | @staticmethod 14 | def get_dependencies(): 15 | """ 16 | Get the dependency states for this state, e.g. states that need to be explicitly enabled on the current object 17 | before the current state is usable. States listed here will be enabled for all objects that have this current 18 | state, and all dependency states will be processed on *all* objects prior to this state being processed on 19 | *any* object. 20 | :return: List of strings corresponding to state keys. 21 | """ 22 | return [] 23 | 24 | @staticmethod 25 | def get_optional_dependencies(): 26 | """ 27 | Get states that should be processed prior to this state if they are already enabled. These states will not be 28 | enabled because of this state's dependency on them, but if they are already enabled for another reason (e.g. 29 | because of an ability or another state's dependency etc.), they will be processed on *all* objects prior to this 30 | state being processed on *any* object. 31 | :return: List of strings corresponding to state keys. 32 | """ 33 | return [] 34 | 35 | def __init__(self, obj, key): # env 36 | super(BaseObjectState, self).__init__() 37 | self.obj = obj 38 | self.name = key 39 | 40 | # def update(self, *args, **kwargs): 41 | # # assert self._initialized, "Cannot update uninitalized state." 42 | # self._update(*args, **kwargs) 43 | 44 | def get_value(self, *args, **kwargs): 45 | # assert self._initialized 46 | self._update(*args, **kwargs) 47 | return self._get_value(*args, **kwargs) 48 | 49 | def set_value(self, *args, **kwargs): 50 | # assert self._initialized 51 | return self._set_value(*args, **kwargs) 52 | 53 | def check_dependencies(self, env): 54 | pass 55 | 56 | 57 | class AbsoluteObjectState(BaseObjectState): 58 | """ 59 | track object states that are absolute (require seed 0_2 object) 60 | """ 61 | def __init__(self, obj, key): # env 62 | super(AbsoluteObjectState, self).__init__(obj, key) 63 | self.type = 'absolute' 64 | self.value = False 65 | 66 | def _update(self, env=None): 67 | pass 68 | 69 | def _get_value(self, env=None): 70 | return self.value 71 | 72 | def _set_value(self, new_value): 73 | self.value = new_value 74 | 75 | 76 | class RelativeObjectState(BaseObjectState): 77 | """ 78 | This class is used to track object states that are relative, e.g. require two objects to compute a value. 79 | Note that subclasses will typically compute values on-the-fly. 80 | """ 81 | def __init__(self, obj, key): # env 82 | super(RelativeObjectState, self).__init__(obj, key) 83 | self.type = 'relative' 84 | 85 | def _update(self, other, env=None): 86 | pass 87 | 88 | def _get_value(self, other, env=None): 89 | raise NotImplementedError 90 | 91 | def _set_value(self, other, new_value): 92 | pass 93 | 94 | 95 | class ObjectProperty(BaseObjectState): 96 | """ 97 | track object states that are absolute (require seed 0_2 object) 98 | """ 99 | def __init__(self, obj, key): # env 100 | super(ObjectProperty, self).__init__(obj, key) 101 | self.type = 'absolute' 102 | 103 | @staticmethod 104 | def _update(self): 105 | pass 106 | 107 | @staticmethod 108 | def _get_value(self, env=None): 109 | return True 110 | 111 | def _set_value(self, new_value): 112 | pass 113 | 114 | 115 | class AbilityState(AbsoluteObjectState): 116 | def __init__(self, obj, key): 117 | super().__init__(obj, key) 118 | icon_path = os.path.join(os.path.dirname(__file__), f'../utils/state_icons/{key}.jpg') 119 | self.icon = img_to_array(icon_path) 120 | 121 | def render(self, img, value=False): 122 | color = [0, 255, 0] if value else [255, 255, 255] 123 | fill_coords(img, point_in_icon(img, self.icon), color) 124 | -------------------------------------------------------------------------------- /mini_behavior/utils/utils.py: -------------------------------------------------------------------------------- 1 | class AttrDict(dict): 2 | def __init__(self, *args, **kwargs): 3 | super(AttrDict, self).__init__(*args, **kwargs) 4 | self.__dict__ = self -------------------------------------------------------------------------------- /mini_behavior/utils/wrappers.py: -------------------------------------------------------------------------------- 1 | import gym 2 | from gym import spaces 3 | from mini_bddl import OBJECT_TO_IDX 4 | 5 | 6 | class MiniBHFullyObsWrapper(gym.core.ObservationWrapper): 7 | """ 8 | Fully observable gridworld using a compact grid encoding 9 | MiniBH encoding is different from MiniGrid encoding 10 | """ 11 | 12 | def __init__(self, env): 13 | super().__init__(env) 14 | 15 | self.unwrapped.use_full_obs = True 16 | self.observation_space.spaces["image"] = spaces.Box( 17 | low=0, 18 | high=255, 19 | shape=(self.env.width, self.env.height, env.grid.pixel_dim), # number of cells 20 | dtype='uint8' 21 | ) 22 | 23 | def observation(self, obs): 24 | return obs 25 | -------------------------------------------------------------------------------- /mini_behavior/window.py: -------------------------------------------------------------------------------- 1 | from gym_minigrid.window import * 2 | import matplotlib.gridspec as gridspec 3 | 4 | 5 | class Window(Window): 6 | """ 7 | Window to draw a gridworld instance using Matplotlib 8 | """ 9 | 10 | def __init__(self, title): 11 | self.no_image_shown = True 12 | self.imshow_obj = None 13 | self.closeup_obj = {'top': None, 14 | 'middle': None, 15 | 'bottom': None, 16 | 'container': None, 17 | } 18 | 19 | # Create the figure and axes 20 | self.fig = plt.figure() 21 | 22 | window = gridspec.GridSpec(1, 6, figure=self.fig) 23 | 24 | self.inventory = gridspec.GridSpecFromSubplotSpec(2, 1, subplot_spec=window[0]) 25 | self.grid = gridspec.GridSpecFromSubplotSpec(1, 4, subplot_spec=window[1:5]) 26 | self.closeup = gridspec.GridSpecFromSubplotSpec(4, 1, subplot_spec=window[5]) 27 | 28 | self.on_grid_ax = self.fig.add_subplot(self.inventory[:1, :]) 29 | self.carrying_ax = self.fig.add_subplot(self.inventory[1:, :]) 30 | self.ax = self.fig.add_subplot(self.grid[:, :], aspect='equal') 31 | self.ax.set_aspect('equal') 32 | self.ax.set_anchor('N') 33 | 34 | self.on_grid_ax.set_title('on grid', fontsize=8, pad=3) 35 | self.carrying_ax.set_title('carrying', fontsize=8, pad=3) 36 | 37 | top_ax = self.fig.add_subplot(self.closeup[:1, :]) 38 | middle_ax = self.fig.add_subplot(self.closeup[1:2, :]) 39 | bottom_ax = self.fig.add_subplot(self.closeup[2:3, :]) 40 | container_ax = self.fig.add_subplot(self.closeup[3:4, :]) 41 | 42 | self.closeup_axes = {'top': top_ax, 43 | 'middle': middle_ax, 44 | 'bottom': bottom_ax, 45 | 'container': container_ax, 46 | } 47 | 48 | for name, ax in self.closeup_axes.items(): 49 | ax.set_aspect('equal') 50 | ax.set_title(name, fontsize=8, pad=3) 51 | ax.set_anchor('N') 52 | 53 | self.closeup_obj[name] = ax.imshow(np.zeros(shape=(1,1,3)), interpolation='bilinear') 54 | 55 | # Show the env name in the window title 56 | self.fig.canvas.manager.set_window_title(title) 57 | 58 | # Turn off x/y axis numbering/ticks 59 | for i, ax in enumerate(self.fig.axes): 60 | ax.tick_params(bottom=False, left=False, labelbottom=False, labelleft=False) 61 | 62 | # Flag indicating the window was closed 63 | self.closed = False 64 | 65 | def close_handler(evt): 66 | self.closed = True 67 | 68 | self.fig.canvas.mpl_connect('close_event', close_handler) 69 | 70 | def set_caption(self, text): 71 | """ 72 | Set/update the caption text below the image 73 | """ 74 | self.ax.set_xlabel(text, labelpad=10) 75 | 76 | def set_inventory(self, env): 77 | """ 78 | Set/update the inventory of objects 79 | """ 80 | def gen_inv(ax, objs): 81 | # gen text 82 | text = "" 83 | for elem in objs: 84 | text += "{}\n".format(elem) 85 | 86 | # add to plot 87 | ax.clear() 88 | # ax.set_ylim(0, 1) 89 | ax.text(0.5, 0.5, text, rotation=0, ha='center', va='center') 90 | 91 | on_grid = [] 92 | carrying = [obj.name for obj in env.obj_instances.values() if obj.check_abs_state(env, 'inhandofrobot')] 93 | for objs in env.objs.values(): 94 | for obj in objs: 95 | if obj.name not in carrying and obj.type != 'door': 96 | on_grid.append(obj.name) 97 | 98 | gen_inv(self.on_grid_ax, on_grid) 99 | gen_inv(self.carrying_ax, carrying) 100 | 101 | self.on_grid_ax.set_title('on grid', fontsize=8, pad=3) 102 | self.carrying_ax.set_title('carrying', fontsize=8, pad=3) 103 | 104 | def show_closeup(self, imgs): 105 | for name, ax in self.closeup_axes.items(): 106 | NAME_INT_MAP = {'container': 0, 'bottom': 1, 'middle': 2, 'top': 3} 107 | img = imgs[NAME_INT_MAP[name]] 108 | # Update the image data 109 | self.closeup_obj[name].set_data(img) 110 | self.closeup_axes[name].set_title(name, fontsize=8, pad=3) 111 | 112 | # Request the window be redrawn 113 | self.fig.canvas.draw_idle() 114 | self.fig.canvas.flush_events() 115 | 116 | def no_closeup(self): 117 | for name, ax in self.closeup_axes.items(): 118 | ax.set_title('') 119 | if self.closeup_obj[name] is not None: 120 | self.closeup_obj[name].set_data(np.ones(shape=(1,1,3))) 121 | 122 | def save_img(self, out_filepath): 123 | self.fig.savefig(out_filepath) 124 | -------------------------------------------------------------------------------- /scripts/load_demos.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import os 3 | import pickle as pkl 4 | 5 | 6 | def load_demo(filepath): 7 | with open(filepath, 'rb') as f: 8 | demo = pkl.load(f) 9 | # demo = [demo[i] for i in range(len(demo))] 10 | demo = list(demo.values()) 11 | return demo 12 | 13 | def load_demos(demo_dir, num_demos=None): 14 | demo_filenames = list(os.listdir(demo_dir)) 15 | demos = [] 16 | if num_demos is not None: 17 | demo_filenames = demo_filenames[: num_demos] 18 | print(len(demo_filenames)) 19 | for demo_filename in demo_filenames: 20 | demo_path = os.path.join(demo_dir, demo_filename) 21 | demo = load_demo(demo_path) 22 | demos += demo 23 | return demos 24 | 25 | 26 | def get_nav_action(init_x, init_y, init_dir, front_is_empty, target_x, target_y, target_dir): 27 | # get action 28 | possible_actions = set() 29 | action_name = None 30 | 31 | if init_x == target_x and init_y == target_y: 32 | if 0 < (init_dir - target_dir) % 4 <= 2: 33 | possible_actions.add('left') 34 | if (init_dir - target_dir) % 4 >= 2: 35 | possible_actions.add('right') 36 | else: 37 | if not front_is_empty: 38 | possible_actions = {'left', 'right'} 39 | else: 40 | if init_x < target_x: 41 | if init_dir == 0: 42 | action_name = 'forward' 43 | else: 44 | if 0 < (init_dir - 0) % 4 <= 2: 45 | possible_actions.add('left') 46 | if (init_dir - 0) % 4 >= 2: 47 | possible_actions.add('right') 48 | if target_y > init_y: 49 | if init_dir == 1: 50 | action_name = 'forward' 51 | else: 52 | if 0 < (init_dir - 1) % 4 <= 2: 53 | possible_actions.add('left') 54 | if (init_dir - 1) % 4 >= 2: 55 | possible_actions.add('right') 56 | if target_x < init_x: 57 | if init_dir == 2: 58 | action_name = 'forward' 59 | else: 60 | if 0 < (init_dir - 2) % 4 <= 2: 61 | possible_actions.add('left') 62 | if (init_dir - 2) % 4 >= 2: 63 | possible_actions.add('right') 64 | if init_y > target_y: 65 | if init_dir == 3: 66 | action_name = 'forward' 67 | else: 68 | if 0 < (init_dir - 3) % 4 <= 2: 69 | possible_actions.add('left') 70 | if (init_dir - 3) % 4 >= 2: 71 | possible_actions.add('right') 72 | 73 | action_name = np.random.choice(list(possible_actions), 1)[0] if action_name is None else action_name 74 | 75 | return action_name 76 | 77 | 78 | demo_dir = './demos/MiniGrid-InstallingAPrinter-8x8-N2-v0/' 79 | demos = load_demos(demo_dir) 80 | print("successfully loaded demos") 81 | print(f"demos length: {len(demos)}") 82 | 83 | -------------------------------------------------------------------------------- /scripts/train_rl_agent.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #SBATCH --account=vision 3 | #SBATCH --partition=svl --qos=normal 4 | #SBATCH --time=12:00:00 5 | #SBATCH --nodes=1 6 | #SBATCH --ntasks-per-node=1 7 | #SBATCH --cpus-per-task=4 8 | #SBATCH --mem=30G 9 | #SBATCH --gres=gpu:1 10 | 11 | #SBATCH --job-name="mini_bh_prelim" 12 | #SBATCH --output=logs/mini_bh_train_slurm_%A.out 13 | #SBATCH --error=logs/mini_bh_train_slurm_%A.err 14 | ####SBATCH --mail-user=emilyjin@stanford.edu 15 | ####SBATCH --mail-type=ALL 16 | 17 | # list out some useful information (optional) 18 | echo "SLURM_JOBID="$SLURM_JOBID 19 | echo "SLURM_JOB_NODELIST"=$SLURM_JOB_NODELIST 20 | echo "SLURM_NNODES"=$SLURM_NNODES 21 | echo "SLURMTMPDIR="$SLURMTMPDIR 22 | echo "working directory = "$SLURM_SUBMIT_DIR 23 | 24 | 25 | ########################################## 26 | # Setting up virtualenv / conda / docker # 27 | ########################################## 28 | module load anaconda3 29 | source activate behavior 30 | echo "conda env activated" 31 | 32 | 33 | ############################################################## 34 | # Setting up LD_LIBRARY_PATH or other env variable if needed # 35 | ############################################################## 36 | export LD_LIBRARY_PATH=/usr/local/cuda-9.1/lib64:/usr/lib/x86_64-linux-gnu 37 | echo "Working with the LD_LIBRARY_PATH: "$LD_LIBRARY_PATH 38 | 39 | 40 | cd /vision/u/emilyjin/mini_behavior/ 41 | 42 | echo "running command: python train_rl_agent.py --task InstallingAPrinter" 43 | python train_rl_agent.py --task InstallingAPrinter 44 | 45 | echo "running command: python train_rl_agent.py --task PuttingAwayDishesAfterCleaning" 46 | python train_rl_agent.py --task PuttingAwayDishesAfterCleaning 47 | 48 | echo "running command: python train_rl_agent.py --task WashingPotsAndPans" 49 | python train_rl_agent.py --task WashingPotsAndPans 50 | 51 | echo "Done" 52 | -------------------------------------------------------------------------------- /scripts/visualize_policy.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | 3 | import gym 4 | import numpy 5 | import random 6 | import mini_behavior 7 | import torch 8 | from stable_baselines3 import PPO 9 | 10 | # For RL visualization 11 | from gym_minigrid.wrappers import ImgObsWrapper 12 | from mini_behavior.utils.wrappers import MiniBHFullyObsWrapper 13 | from mini_behavior.register import register 14 | 15 | # Parse arguments 16 | parser = argparse.ArgumentParser() 17 | parser.add_argument("--env", 18 | default="InstallingAPrinter", 19 | help="name of the environment to be run (REQUIRED)") 20 | parser.add_argument("--room_size", type=int, default=10) 21 | parser.add_argument("--max_steps", type=int, default=1000) 22 | parser.add_argument("--dense_reward", action="store_true") 23 | parser.add_argument("--seed", type=int, default=20, 24 | help="random seed (default: 0)") 25 | parser.add_argument("--shift", type=int, default=0, 26 | help="number of times the environment is reset at the beginning (default: 0)") 27 | parser.add_argument("--pause", type=float, default=0.25, 28 | help="pause duration between two consequent actions of the agent (default: 0.seed 0_2)") 29 | parser.add_argument("--gif", type=str, default=None, 30 | help="store output as gif with the given filename") 31 | parser.add_argument("--episodes", type=int, default=1000000, 32 | help="number of episodes to visualize") 33 | parser.add_argument("--reset", action="store_true", default=False, 34 | help="Keep resetting for testing initialization") 35 | parser.add_argument("--norend", action="store_true", default=False, 36 | help="Whether to render") 37 | parser.add_argument("--full_obs", action="store_true", default=False, 38 | help="Whether to use fully observable wrapper") 39 | parser.add_argument("--load_model", default="", 40 | help="Whether to load from") 41 | 42 | args = parser.parse_args() 43 | 44 | device = torch.device("cuda" if torch.cuda.is_available() else "cpu") 45 | 46 | def seed(seed): 47 | random.seed(seed) 48 | numpy.random.seed(seed) 49 | torch.manual_seed(seed) 50 | if torch.cuda.is_available(): 51 | torch.cuda.manual_seed_all(seed) 52 | 53 | # Set seed for all randomness sources 54 | seed(args.seed) 55 | 56 | # Set device 57 | print(f"Device: {device}\n") 58 | 59 | 60 | # Env wrapping 61 | env_name = f"MiniGrid-{args.env}-{args.room_size}x{args.room_size}-N2-v0" 62 | 63 | print(f'register env {args.env}') 64 | 65 | kwargs = {"room_size": args.room_size, "max_steps": args.max_steps} 66 | if args.dense_reward: 67 | assert args.env in ["PuttingAwayDishesAfterCleaning", "WashingPotsAndPans"] 68 | kwargs["dense_reward"] = True 69 | 70 | register( 71 | id=env_name, 72 | entry_point=f'mini_behavior.envs:{args.env}Env', 73 | kwargs=kwargs 74 | ) 75 | 76 | # Load environment 77 | env = gym.make(env_name) 78 | if args.full_obs: 79 | env = MiniBHFullyObsWrapper(env) 80 | env = ImgObsWrapper(env) 81 | env.seed(args.seed) 82 | 83 | for _ in range(args.shift): 84 | env.reset() 85 | print("Environment loaded\n") 86 | 87 | load_model = args.load_model 88 | 89 | if load_model: 90 | # Load Model 91 | model = PPO.load(f"model/{load_model}", env=env) 92 | print("model loaded") 93 | 94 | 95 | if args.gif: 96 | from array2gif import write_gif 97 | frames = [] 98 | 99 | if not args.norend: 100 | # Create a window to view the environment 101 | env.render('human') 102 | 103 | for episode in range(args.episodes): 104 | obs = env.reset() 105 | 106 | # To test reset 107 | if args.reset: 108 | while True: 109 | env.render('human') 110 | obs = env.reset() 111 | 112 | while True: 113 | if not args.norend: 114 | env.render('human') 115 | if args.gif: 116 | frames.append(numpy.moveaxis(env.render("rgb_array"), 2, 0)) 117 | 118 | 119 | if load_model: 120 | action, _ = model.predict(obs) 121 | else: 122 | action = env.action_space.sample() 123 | 124 | obs, reward, done, info = env.step(action) 125 | 126 | if env.mode == "cartesian": 127 | print(env.action_list[action]) 128 | else: 129 | print(env.actions(action).name) 130 | 131 | print(f"reward: {reward}\n") 132 | 133 | if done: 134 | print("episode done") 135 | print(f"reward: {reward}") 136 | break 137 | # import sys 138 | # import numpy as np 139 | # np.set_printoptions(threshold=sys.maxsize) 140 | # print(obs) 141 | # import ipdb 142 | # ipdb.set_trace() 143 | 144 | print("one episode done \n") 145 | 146 | if args.gif: 147 | print("Saving gif... ", end="") 148 | write_gif(numpy.array(frames), args.gif+".gif", fps=1/args.pause) 149 | print("Done.") 150 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | with open("README.md") as fh: 4 | long_description = "" 5 | header_count = 0 6 | for line in fh: 7 | if line.startswith("##"): 8 | header_count += 1 9 | if header_count < 2: 10 | long_description += line 11 | else: 12 | break 13 | 14 | # pytest is pinned to 7.0.1 as this is last version for python 3.6 15 | extras = {"testing": ["pytest==7.0.1"]} 16 | 17 | setup( 18 | name="mini_behavior", 19 | author="Stanford & UT Austin", 20 | author_email="jiahengh@utexas.edu", 21 | classifiers=[ 22 | "Development Status :: 5 - Production/Stable", 23 | "Programming Language :: Python :: 3", 24 | "Programming Language :: Python :: 3.7", 25 | "Programming Language :: Python :: 3.8", 26 | "Programming Language :: Python :: 3.9", 27 | "Programming Language :: Python :: 3.10", 28 | ], 29 | version="1.1.0", 30 | keywords="memory, environment, agent, rl, gym", 31 | url="https://github.com/StanfordVL/mini_behavior", 32 | description="Minimalistic gridworld reinforcement learning environments", 33 | extras_require=extras, 34 | packages=["mini_behavior", "mini_behavior.envs"], 35 | license="Apache", 36 | long_description=long_description, 37 | long_description_content_type="text/markdown", 38 | install_requires=[ 39 | "gym==0.21", 40 | "numpy>=1.18.0", 41 | "matplotlib>=3.0", 42 | "h5py", 43 | ], 44 | python_requires=">=3.7", 45 | tests_require=extras["testing"], 46 | ) 47 | -------------------------------------------------------------------------------- /train_rl_agent.py: -------------------------------------------------------------------------------- 1 | import gym 2 | from gym_minigrid.wrappers import ImgObsWrapper 3 | from mini_behavior.utils.wrappers import MiniBHFullyObsWrapper 4 | from mini_behavior.register import register 5 | import mini_behavior 6 | from stable_baselines3 import PPO 7 | import numpy as np 8 | from stable_baselines3.common.env_util import make_vec_env 9 | from stable_baselines3.common.torch_layers import BaseFeaturesExtractor 10 | import torch.nn as nn 11 | import torch 12 | import argparse 13 | import wandb 14 | from wandb.integration.sb3 import WandbCallback 15 | 16 | 17 | parser = argparse.ArgumentParser() 18 | parser.add_argument("--task", required=True, help='name of task to train on') 19 | parser.add_argument("--partial_obs", default=True) 20 | parser.add_argument("--room_size", type=int, default=10) 21 | parser.add_argument("--max_steps", type=int, default=1000) 22 | parser.add_argument("--total_timesteps", type=int, default=5e6) 23 | parser.add_argument("--dense_reward", action="store_true") 24 | parser.add_argument("--policy_type", default="CnnPolicy") 25 | args = parser.parse_args() 26 | partial_obs = args.partial_obs 27 | 28 | 29 | class MinigridFeaturesExtractor(BaseFeaturesExtractor): 30 | def __init__(self, observation_space: gym.Space, features_dim: int = 512, normalized_image: bool = False) -> None: 31 | super().__init__(observation_space, features_dim) 32 | n_input_channels = observation_space.shape[0] 33 | self.cnn = nn.Sequential( 34 | nn.Conv2d(n_input_channels, 32, (2, 2)), 35 | nn.ReLU(), 36 | nn.Conv2d(32, 32, (2, 2)), 37 | nn.ReLU(), 38 | nn.Conv2d(32, 64, (2, 2)), 39 | nn.ReLU(), 40 | nn.Flatten(), 41 | ) 42 | 43 | # Compute shape by doing one forward pass 44 | with torch.no_grad(): 45 | n_flatten = self.cnn(torch.as_tensor(observation_space.sample()[None]).float()).shape[1] 46 | 47 | self.linear = nn.Sequential(nn.Linear(n_flatten, features_dim), nn.ReLU()) 48 | 49 | def forward(self, observations: torch.Tensor) -> torch.Tensor: 50 | return self.linear(self.cnn(observations)) 51 | 52 | 53 | policy_kwargs = dict( 54 | features_extractor_class=MinigridFeaturesExtractor, 55 | features_extractor_kwargs=dict(features_dim=128), 56 | ) 57 | 58 | # Env wrapping 59 | env_name = f"MiniGrid-{args.task}-{args.room_size}x{args.room_size}-N2-v0" 60 | 61 | print(f'register env {args.task}') 62 | 63 | kwargs = {"room_size": args.room_size, "max_steps": args.max_steps} 64 | if args.dense_reward: 65 | assert args.task in ["PuttingAwayDishesAfterCleaning", "WashingPotsAndPans"] 66 | kwargs["dense_reward"] = True 67 | 68 | register( 69 | id=env_name, 70 | entry_point=f'mini_behavior.envs:{args.task}Env', 71 | kwargs=kwargs 72 | ) 73 | 74 | config = { 75 | "policy_type": args.policy_type, 76 | "total_timesteps": args.total_timesteps, 77 | "env_name": env_name, 78 | } 79 | 80 | print('init wandb') 81 | run = wandb.init( 82 | project=env_name, 83 | config=config, 84 | sync_tensorboard=True, # auto-upload sb3's tensorboard metrics 85 | monitor_gym=False, # auto-upload the videos of agents playing the game 86 | save_code=True, # optional 87 | ) 88 | 89 | print('make env') 90 | env = gym.make(env_name) 91 | if not args.partial_obs: 92 | env = MiniBHFullyObsWrapper(env) 93 | env = ImgObsWrapper(env) 94 | 95 | print('begin training') 96 | # Policy training 97 | model = PPO(config["policy_type"], env, n_steps=8000, policy_kwargs=policy_kwargs, verbose=1, tensorboard_log=f"./runs/{run.id}") 98 | model.learn(config["total_timesteps"], callback=WandbCallback(model_save_path=f"models/{run.id}")) 99 | 100 | if not partial_obs: 101 | model.save(f"models/ppo_cnn/{env_name}") 102 | else: 103 | model.save(f"models/ppo_cnn_partial/{env_name}") 104 | 105 | run.finish() 106 | --------------------------------------------------------------------------------