Skip to content

Instantly share code, notes, and snippets.

@kvas7andy
Last active August 15, 2022 09:00
Show Gist options
  • Save kvas7andy/55d7ba0653ba4d8bfc582dd187d49974 to your computer and use it in GitHub Desktop.
Save kvas7andy/55d7ba0653ba4d8bfc582dd187d49974 to your computer and use it in GitHub Desktop.
Brief explanation of MUNOS simulator usage

Intro

MINOS - simulator of the agent , navigating in indoor environment. Based on WebGL (Graphic library on javascript), server <-> client framework with configuration files.

Links to original code and my fork with several update and recent code (gist maybe not up-to-date).

Interactive play video.

MINOS framework image, from original paper )

Predefined datasets

Use SUNCG/Matterport3D (Mp3D) as predefined datasets. Use special partial datasets for MINOS simulator (ask authors of the datasets).

  • download SUNCG via link, you get from authors' email (suncg.v2.zip, ~9 Gb)
  • download Mp3D via .py script from author's email (~ 5 Gb)
    • you download "minos" task (still without object segmentation)
    • you can download any other task or bunch of data (look at "download_mp.py" script). For ex.: "semantic_voxel_label_data", "semantic_voxel_label_models", "region_classification_data", "region_classification_models", "region_segmentations" (data only: .ply and .json files). A bit later about it.

Data:

  • RGB, RGBA, Grayscale
  • Depth
  • Segmentation with predefined labels (SUNCG, Matterport3D - only in full dataset)
  • Forces
  • Normals from meshes
  • Measurements (velocity, accelaration)

Features:

  • Retexturing (SUNCG)
  • Partialy edit FOV (vertical only: added in enhancements)
  • Empty room/ clutter concrete objects
  • Task parameters: goal specification, reward function for each step, success objective

Sum up, search for data configuration in

  • config/sensors.yml: preconfigured "sensors" to use, with its name, in various tasks (via configuration files). Change various parameters, add your own camera, depth sensor etc.
  • config/envs/.py: preconfigured configuration files for tasks, added in MINOS paper. State usage of concrete sensors (observations), task-related parameters (look at Features) + scene sampling, train/test/val split
  • Other configurations and parameters documented (briefly) in API.md, terminal arguments for execution shown in config/sim_config.py & config/sim_args.py.

Made my own minos_test_mp3d.py and minos_test_suncg.py to specify 3d scenes for generating RGBA, depth and objectId (semantic) data. (See below)

Installation

Use installation guide from minosworld/minos github

  1. Download data for minos (SUNCG/Matterport3D) via links from authors (or ask me). Place them in one folder for convinience.
  2. Download nvm and install node. IssueSolution: use node > 9.4.0. Check via node -v, install via nvm install node 9.4.0 nvm alias default 9.4.0
  3. Inside minos/server folder install server part of the framework npm install.

IssueSolution: can be problems with pkg-config, x11, xi and xext packages (no packages installed). Install them via sudo apt-get install pkg-config xserver-xorg-dev libxext-dev libxi-dev

IssueSolution: with little modification of main code, you can start server manually, without the start of client part (see below)

IssueSolution: can be problems with socketio_client (wrong version from ubuntu repositories). Use this code

sudo apt-get uninstall socketio_client
pip install https://github.com/msavva/socketIO-client-2/zipball/master

This repository is commented in file .../minos_python_repackage/minos/lib/Simulator.py and should be updated by your own.

node [--max-old-space-size=4096 {default: 4096}] server/server.js [--port 4444 {default: 4899}]

But, one server can work only with one client simultaneously! 4. Via virtualenv or throughout your system install packages via pip3 install -r requirements.txt. This will install openai lib gym as well and make access to minos lib 5. Use export NODE_BASE_URL=path/to/data_parent_dir (or use another variants, see minosworld/minos github) 6. Use it! or install more (gym_minos openai gym environment, minos_unreal Reinforcement learning implementation of algorithm for navigation)

Open bugs, issues

  1. Parial FOV editing (only vertical FOV, which change horizontal FOV)
  2. Memory leak when not closing simulator's server (done, but not tested in my fork) No problem now!//3. Error with non-square resolution (current issue on original github) Evade this room (filter parameter)//4. Problem with rendering of several scenes (make an issue on github)
  3. No object segmentation data preloaded by mp3d_task (loaded by myself, current issue on github)

To use on a headless server

1.1 solution: Install NVIDIA drivers and CUDA without opengl files see here

1.2 solution, Easier: prepend LD_LIBRARY_PATH with path to mesa libraries (preinstall them as libgl1-mesa, mesa-utils)

2.1 solution: nvidia-xconfig - have to try (will update):)

2.2 solution: use nvidia/opengl or even cudagl lib - tried, but I had problems. Good luck to you and let me know about SUCCESS!

Usage

Manual output

Use pygame_client for python3 -m tools.pygame_client [--key1 --key2 pararm] - manual agent control in simulator via keyboard

Example:

python3 -m tools.pygame_client --depth -s normal -s objectId -s objectType -s map --navmap --width 128 --height 128

(Not recommended) For separate execution of server and client part (1 client for 1 simulator only):

python3 -m tools.pygame_client [--depth] [-s normal] [-s objectType] [--width 244] [--height 244] [--save_video test] [--port 4444 {default: 4899}] (need modify files, a little)

Sensor output specification (in command line)

  • --depth display depth
  • -s something display sensor:
    • normal - colored normals' map;
    • objectId - colored labels of objects, by instance number;
    • objectType - colored ..., by type
    • map - show topview grayscale map
    • --navmap - show shortestpath for agent to specified goal on topview map
    • --width, --height - display and observations resolution!!! (display only rgba, no matter what observations you look for)
  • --agent_config: name of config file for agent (without ".yml"), predefined in config folder (agent_gridworld - discrete, agent_continous - continous, etc.), you can write yours. Include physical params (weight, size, ...) and movement params (speed, rotation speed, ...)
  • --env_config: name of config task-related environment for agent (without ".py"). Predefined in config/envs folder, you can write yours. Include task-specification ("pointgoal", "roomgoal" or "objectgoal"), scene specification, i.e. path to table of scenes and train/test/val split of states (in config), observations specification by name of the sensor, etc.
  • Others you can find in sim_config.py file with default values!!!

Generating images task

You need to modify code by yourself to gain observations from data and save them as images or video (or just use my rewrited demo.py script, see below). First of all, use env_config and agent_config to state necessary parameters, like observation types, resolution for environment.

Other scripts

There are plenty scripts useful for RL tasks, like generating RL datasets (like "scene<->initial_place" configurations, to use for benchmarking by other algorithms).

OpenAI gym API

OpenAI gym API is used as prebuild python package gym/gym_minos, which is then used as 'indoor-env' environemnt in your local copy of gym library.

We can use this API for generating control logic and automatical generation of output sensor data.

Install

(if installing separately): via pip install -e . inside gym folder. (better use origin/python-repackage branch, rather then origin/master)

Execution

Then look inside gym/demo.py file. I rewrote code for generating sensor output from different scenes and locations, as 4 views of 90 degree camera rotations. Use only env_config and agent_config to execute gym session:

python3 demo.py --env_config objectgoal_suncg_mf --agent_config agent_gridworld --width 128 --height 128

Change width and height for another resolution of images (only square, by now). Displayed window will be 4 times bigger (predefined in pygame module).

My implementation uses own minos_test_suncg.py and minos_test_mp3d.py environmental configs, plus agent_gridworld config. Action space in gym environment 'indoor-v0' consists of 3 actions: turnLeft, turnRight, forward (parametrized with available_controls in config file, see RoomSimulator.py).

def run_gym(sim_args):
    env = gym.make('indoor-v0')
    env.configure(sim_args)
    try:
        print('Running MINOS gym example')
        for i_episode in range(100):
            print('Starting episode %d' % i_episode)
            observation = env.reset()
            done = False
            num_steps = 0
            name = sim_args['env_config'].split('_')[-1]
            while not done:
                img_prefix = 'pics/'
                actions_str =[None] + ['turnRight']*3
                for action_i, action_str in enumerate(actions_str):
                    env.render(mode='human')
                    if acntion_str is not None:
                        observation, reward, done, info = env.step(actions_dict[action_str])
                    img = observation['observation']['sensors']['color']['data']
                    img = img.reshape((img.shape[1], img.shape[0], img.shape[2]))
                    scipy.misc.toimage(img, cmin=0, cmax=255).save(name + '_' +img_prefix + str(i_episode) + '_' + str(action_i) + 'img' + '.png')
                    depth = observation['observation']['sensors']['depth']['data']
                    depth = depth.reshape((depth.shape[1], depth.shape[0], depth.shape[2]))
                    depth *= (255.0 / depth.max())  # naive rescaling for visualization
                    depth = depth.astype(np.uint8)
                    scipy.misc.toimage(depth, cmin=0, cmax=255).save(name + '_' +img_prefix + str(i_episode) + '_' + str(action_i) +'depth' + '.png')
                    if 'suncg'==name:
                        objectId = observation['observation']['sensors']['objectId']['data']
                        scipy.misc.toimage(objectId, cmin=0, cmax=255).save(name + '_' +img_prefix + str(i_episode)+ '_' + str(action_i)  + 'objectId' + '.png')
                num_steps += 1
                done = True
    except Exception as e:
        print(traceback.format_exc())
env._close()

Addtional options

  1. Use predefined episodes (in original repository) in parameter 'states_file', with concrete train/val/test split. Specify type of dataset in 'episode_schedule' ('train'/'val'/'test'). Specify filters for room types, Ids and characteristics with 'scene', 'scene_filter' and 'episode_filter'. See other params in config/sim_config.py (i.e. in gist config). More in issue and API.md.
  2. Use another resolution, with 'resolution' parameter, width and height, and 'resize: True' for sensors yaml file.
  3. Use objectId information for SUNCG, and wait in my fork or (original code)[] for Matterport3D objectID access via observations.
SUNCG

1_3img 1_3depth

Matterport3D

3_2img 3_2depth

Video SUNCG images generation and Matterport3D images generation. Only RGB display.

Other example - A3C UNREAL with MINOS

Links to original code and my fork as MS thesis repository

Task

Additional API

Additional API include class Environment, which aggregate deepmind lab maze, gym and indoor_environment for MINOS simulator. IndoorEnvironment class is a wrapper for RoomSimulator class in minos library (lib/RoomSimulator.py). This package imports sim_config and RoomSimulator from minos from minos.lib.RoomSimulator import RoomSimulator; from minos.config import sim_config, as well as add Tensorflow Unreal model to provide code for training, display, evaluation and vizualisation of NN weights (original repository is a fork of A3C UNREAL model for DeepMind-lab maze)

Usage

See main usage in README.md

  • main.py - training of A3C model with 4 simultaneously trained simulators
  • display.py - display training process with score, value function and policy
  • evaluate.py - evaluate success rate on test scenes. See example in gist

Video of slightly trained algorithm

MINOS rendering and processing unit

Included in server.js with bundle of STK module.

Matterport3D and SUNCG available data

See SUNCG/Matterport3D.

Some examples:

Why to choose MINOS?

Pros Cons
Multisensor output No point-cloud output
Augmentation functionality (retexturing, sensors parameters etc.) -//-
support SUNCG & Matterport3D (few simulators have code for this) -//-
Open Source, realtime support, JS + Python Issues, bugs, enhancements DIY
Mostly for RL tasks -//-

And now: REAL DEMO!

#!/usr/bin/env python3
import argparse
import gym
import gym_minos
import time
import sys
import traceback
from minos.config import sim_config
from minos.config.sim_args import add_sim_args_basic
import scipy.misc
import numpy as np
actions_dict = {'forwards': [0, 0, 1], 'turnLeft': [1, 0, 0], 'turnRight':[0, 1, 0], 'idle':[0, 0, 0]};
def run_gym(sim_args):
env = gym.make('indoor-v0')
env.configure(sim_args)
try:
print('Running MINOS gym example')
for i_episode in range(100):
print('Starting episode %d' % i_episode)
observation = env.reset()
done = False
num_steps = 0
name = sim_args['env_config'].split('_')[-1]
while not done:
img_prefix = 'pics/'
actions_str =['idle'] + ['turnRight']*3
for action_i, action_str in enumerate(actions_str):
env.render(mode='human')
observation, reward, done, info = env.step(actions_dict[action_str])
img = observation['observation']['sensors']['color']['data']
img = img.reshape((img.shape[1], img.shape[0], img.shape[2]))
scipy.misc.toimage(img, cmin=0, cmax=255).save(name + '_' +img_prefix + str(i_episode) + '_' + str(action_i) + 'img' + '.png')
depth = observation['observation']['sensors']['depth']['data']
depth = depth.reshape((depth.shape[1], depth.shape[0], depth.shape[2]))
depth *= (255.0 / depth.max()) # naive rescaling for visualization
depth = depth.astype(np.uint8)
scipy.misc.toimage(depth, cmin=0, cmax=255).save(name + '_' +img_prefix + str(i_episode) + '_' + str(action_i) +'depth' + '.png')
if 'suncg'==name:
objectId = observation['observation']['sensors']['objectId']['data']
scipy.misc.toimage(objectId, cmin=0, cmax=255).save(name + '_' +img_prefix + str(i_episode)+ '_' + str(action_i) + 'objectId' + '.png')
num_steps += 1
done = True
except Exception as e:
print(traceback.format_exc())
env._close()
def main():
parser = argparse.ArgumentParser(description='MINOS gym wrapper')
add_sim_args_basic(parser)
parser.add_argument('--env_config',
default='objectgoal_suncg_sf',
help='Environment configuration file')
args = parser.parse_args()
sim_args = sim_config.get(args.env_config, vars(args))
run_gym(sim_args)
if __name__ == "__main__":
main()
#!/usr/bin/env python
# Downloads MP public data release
# Run with ./download_mp.py (or python download_mp.py on Windows)
# -*- coding: utf-8 -*-
import argparse
import collections
import os
import tempfile
import urllib
BASE_URL = 'http://dovahkiin.stanford.edu/matterport/public/'
RELEASE = 'v1/scans'
RELEASE_TASKS = 'v1/tasks/'
RELEASE_SIZE = '1.3TB'
TOS_URL = BASE_URL + 'MP_TOS.pdf'
FILETYPES = [
'cameras',
'matterport_camera_intrinsics',
'matterport_camera_poses',
'matterport_color_images',
'matterport_depth_images',
'matterport_hdr_images',
'matterport_mesh',
'matterport_skybox_images',
'undistorted_camera_parameters',
'undistorted_color_images',
'undistorted_depth_images',
'undistorted_normal_images',
'house_segmentations',
'region_segmentations',
'image_overlap_data',
'poisson_meshes',
'sens'
]
TASK_FILES = {
'keypoint_matching_data': 'keypoint_matching/data.zip',
'keypoint_matching_models': 'keypoint_matching/models.zip',
'surface_normal_data': 'surface_normal/data_list.zip',
'surface_normal_models': 'surface_normal/models.zip',
'region_classification_data': 'region_classification/data.zip',
'region_classification_models': 'region_classification/models.zip',
'semantic_voxel_label_data': 'semantic_voxel_label/data.zip',
'semantic_voxel_label_models': 'semantic_voxel_label/models.zip',
'minos': 'mp3d_minos.zip',
}
def get_release_scans(release_file):
scan_lines = urllib.urlopen(release_file)
scans = []
for scan_line in scan_lines:
scan_id = scan_line.rstrip('\n')
scans.append(scan_id)
return scans
def download_release(release_scans, out_dir, file_types):
print('Downloading MP release to ' + out_dir + '...')
for scan_id in release_scans:
scan_out_dir = os.path.join(out_dir, scan_id)
download_scan(scan_id, scan_out_dir, file_types)
print('Downloaded MP release.')
def download_file(url, out_file):
out_dir = os.path.dirname(out_file)
if not os.path.isfile(out_file):
print '\t' + url + ' > ' + out_file
fh, out_file_tmp = tempfile.mkstemp(dir=out_dir)
f = os.fdopen(fh, 'w')
f.close()
urllib.urlretrieve(url, out_file_tmp)
os.rename(out_file_tmp, out_file)
else:
print('WARNING: skipping download of existing file ' + out_file)
def download_scan(scan_id, out_dir, file_types):
print('Downloading MP scan ' + scan_id + ' ...')
if not os.path.isdir(out_dir):
os.makedirs(out_dir)
for ft in file_types:
url = BASE_URL + RELEASE + '/' + scan_id + '/' + ft + '.zip'
out_file = out_dir + '/' + ft + '.zip'
download_file(url, out_file)
print('Downloaded scan ' + scan_id)
def download_task_data(task_data, out_dir):
print('Downloading MP task data for ' + str(task_data) + ' ...')
for task_data_id in task_data:
if task_data_id in TASK_FILES:
file = TASK_FILES[task_data_id]
url = BASE_URL + RELEASE_TASKS + '/' + file
localpath = os.path.join(out_dir, file)
localdir = os.path.dirname(localpath)
if not os.path.isdir(localdir):
os.makedirs(localdir)
download_file(url, localpath)
print('Downloaded task data ' + task_data_id)
def main():
parser = argparse.ArgumentParser(description=
'''
Downloads MP public data release.
Example invocation:
python download_mp.py -o base_dir --id ALL --type object_segmentations --task_data semantic_voxel_label_data semantic_voxel_label_models
The -o argument is required and specifies the base_dir local directory.
After download base_dir/v1/scans is populated with scan data, and base_dir/v1/tasks is populated with task data.
Unzip scan files from base_dir/v1/scans and task files from base_dir/v1/tasks/task_name.
The --type argument is optional (all data types are downloaded if unspecified).
The --id ALL argument will download all house data. Use --id house_id to download specific house data.
The --task_data argument is optional and will download task data and model files.
''',
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-o', '--out_dir', required=True, help='directory in which to download')
parser.add_argument('--task_data', default=[], nargs='+', help='task data files to download. Any of: ' + ','.join(TASK_FILES.keys()))
parser.add_argument('--id', default='ALL', help='specific scan id to download or ALL to download entire dataset')
parser.add_argument('--type', nargs='+', help='specific file types to download. Any of: ' + ','.join(FILETYPES))
args = parser.parse_args()
print('By pressing any key to continue you confirm that you have agreed to the MP terms of use as described at:')
print(TOS_URL)
print('***')
print('Press any key to continue, or CTRL-C to exit.')
key = raw_input('')
release_file = BASE_URL + RELEASE + '.txt'
release_scans = get_release_scans(release_file)
file_types = FILETYPES
# download specific file types?
if args.type:
if not set(args.type) & set(FILETYPES):
print('ERROR: Invalid file type: ' + file_type)
return
file_types = args.type
if args.id and args.id != 'ALL': # download single scan
scan_id = args.id
if scan_id not in release_scans:
print('ERROR: Invalid scan id: ' + scan_id)
else:
out_dir = os.path.join(args.out_dir, RELEASE, scan_id)
download_scan(scan_id, out_dir, file_types)
elif 'minos' not in args.task_data and args.id == 'ALL' or args.id == 'all': # download entire release
if len(file_types) == len(FILETYPES):
print('WARNING: You are downloading the entire MP release which requires ' + RELEASE_SIZE + ' of space.')
else:
print('WARNING: You are downloading all MP scans of type ' + file_types[0])
print('Note that existing scan directories will be skipped. Delete partially downloaded directories to re-download.')
print('***')
print('Press any key to continue, or CTRL-C to exit.')
key = raw_input('')
out_dir = os.path.join(args.out_dir, RELEASE)
download_release(release_scans, out_dir, file_types)
# task data
if args.task_data:
if set(args.task_data) & set(TASK_FILES.keys()): # download task data
out_dir = os.path.join(args.out_dir, RELEASE_TASKS)
download_task_data(args.task_data, out_dir)
else:
print('ERROR: Unrecognized task data id: ' + args.task_data)
return
if __name__ == "__main__": main()
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import traceback
import tensorflow as tf
import numpy as np
from environment.environment import Environment
from model.model import UnrealModel
from train.experience import ExperienceFrame
from options import get_options
# get command line args
flags = get_options("evaluate")
class Evaluate(object):
def __init__(self):
self.action_size = Environment.get_action_size(flags.env_type, flags.env_name)
self.objective_size = Environment.get_objective_size(flags.env_type, flags.env_name)
self.global_network = UnrealModel(self.action_size,
self.objective_size,
-1,
flags.use_lstm,
flags.use_pixel_change,
flags.use_value_replay,
flags.use_reward_prediction,
0.0,
0.0,
"/cpu:0",
for_display=True)
self.environment = Environment.create_environment(flags.env_type, flags.env_name,
env_args={'episode_schedule': flags.split,
'log_action_trace': flags.log_action_trace,
'max_states_per_scene': flags.episodes_per_scene,
'episodes_per_scene_test': flags.episodes_per_scene})
self.episode_reward = 0
def update(self, sess):
self.process(sess)
def is_done(self):
return self.environment.is_all_scheduled_episodes_done()
def choose_action(self, pi_values):
return np.random.choice(range(len(pi_values)), p=pi_values)
def process(self, sess):
last_action = self.environment.last_action
last_reward = np.clip(self.environment.last_reward, -1, 1)
last_action_reward = ExperienceFrame.concat_action_and_reward(last_action, self.action_size,
last_reward, self.environment.last_state)
if not flags.use_pixel_change:
pi_values, v_value = self.global_network.run_base_policy_and_value(sess,
self.environment.last_state,
last_action_reward)
else:
pi_values, v_value, pc_q = self.global_network.run_base_policy_value_pc_q(sess,
self.environment.last_state,
last_action_reward)
action = self.choose_action(pi_values)
state, reward, terminal, pixel_change = self.environment.process(action)
self.episode_reward += reward
if terminal:
self.environment.reset()
self.episode_reward = 0
def main(args):
try:
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.1) # avoid using all gpu memory
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))
sess.run(tf.global_variables_initializer())
evaluate = Evaluate()
saver = tf.train.Saver()
checkpoint = tf.train.get_checkpoint_state(flags.checkpoint_dir)
if checkpoint and checkpoint.model_checkpoint_path:
saver.restore(sess, checkpoint.model_checkpoint_path)
print("checkpoint loaded:", checkpoint.model_checkpoint_ path)
else:
print("Could not find old checkpoint")
while not evaluate.is_done():
evaluate.update(sess)
except Exception as e:
print(traceback.format_exc())
finally:
evaluate.environment.stop()
if __name__ == '__main__':
tf.app.run()
from minos.lib.util.measures import MeasureDistDirTime
config = {
'task': 'point_goal',
'goal': {'position': 'random', 'radius': 0.25},
'observations': {'color': True, 'forces': False, 'audio': False, 'objectId': False, 'depth': True},
'measure_fun': MeasureDistDirTime(goal_dist_threshold=0.4),
'reward_type': 'dist_time',
'agent': {'radialClearance': 0.2},
'scene': {'dataset': 'mp3d'},
'scenes_file': '../data/scenes.mp3d.csv',
'states_file': '../data/episode_states.mp3d.csv.bz2',
'num_episodes_per_scene': 100,
'max_states_per_scene': 10,
'scene_filter': lambda s: 2 < s['nrooms'] < 25 and s['nlevels'] == 1,
'episode_filter': lambda e: e['pathNumRooms'] > 0,
'objective_size': 4 # For UNREAL
}
from minos.lib.util.measures import MeasureDistDirTime
config = {
'task': 'point_goal',
'goal': {'position': 'random', 'radius': 0.25},
'observations': {'color': True, 'forces': False, 'audio': False, 'objectId': True, 'depth': True},
'measure_fun': MeasureDistDirTime(goal_dist_threshold=0.4),
'reward_type': 'dist_time',
'agent': {'radialClearance': 0.2},
'scenes_file': '../data/scenes.multiroom.csv',
'states_file': '../data/episode_states.suncg.csv.bz2',
'scene': {'arch_only': False, 'retexture': True, 'empty_room': False, 'dataset': 'p5dScene'},
'scene_filter': lambda s: s['nrooms'] == 2,
'episode_filter': lambda e: e['pathNumDoors'] > 0,
'objective_size': 4 # For UNREAL
}
---
- name: group # name of group (can be anything you want)
type: group # defines group of sensors at the same position and orientation
modes:
- name: color # image camera
type: color
renderer: main
encoding: gray # encoding: 'gray' for grayscale, 'rgba' for color
- name: objectId # object id mask
type: semantic
encoding: objectId
countPixels: true # whether to return pixel counts
- name: objectType # object category mask
type: semantic
encoding: objectType
- name: roomId # room i d mask
type: semantic
encoding: roomId
- name: roomType # room type mask
type: semantic
encoding: roomType
- name: normal # surface normals
type: normal
encoding: xyza
near: 0.001 # camera near in meters
far: 20 # camera far in meters
fov: 45 # vertical field of view in degrees (>0 to <180)
configuration: positional
position: [[0, 0.6, 0]]
orientation: [[0, 0, -1]]
resolution: [84, 84]
resize: true
active: true
- name: depth # depth camera
type: depth
configuration: positional
position: [[0, 0.6, 0]]
orientation: [[0, 0, -1]]
resolution: [84, 84]
resize: true
encoding: depth
datatype: float32
near: 0.1 # camera near in meters
far: 20 # camera far in meters
fov: 45 # vertical field of view in degrees (>0 to <180)
metersToUnit: 1
noise_model:
name: kinect
type: simple
clip: [0.5, 4]
noise: ["gaussian", 0, 0.01]
noise: false
active: true
- name: audio # audio sensors
type: audio
configuration: radial
position: [[0.15, 0.6, 1.57], [0.15, 0.6, 4.71]]
orientation: [[1, 0, 0], [-1, 0, 0]]
resolution: [1]
encoding: pcm
active: true
- name: force # force sensors
type: force
configuration: radial-group
position: [[0, -0.25, 0]]
orientation: [[0, 0, 1]]
radial: [0.25, 4, 0, 6.28]
resolution: [1, 1, 1]
encoding: raw_contact
active: true
import collections
import copy
import json
import os
import pprint
import time
from minos.lib.util import measures
def resolve_relative_path(path):
return os.path.join(os.path.dirname(__file__), path)
def get_scene_params(arch_only=False, retexture=False, empty_room=False, dataset='p5dScene'):
if arch_only and empty_room:
raise Exception('Cannot specify both arch_only and empty_room for scene params')
replace_doors_file = resolve_relative_path('./replace_doors.json')
with open(replace_doors_file, 'r') as f:
replace_doors = json.load(f)
return {
'source': dataset,
'archOnly': arch_only, 'retexture': retexture,
'textureSet': 'train',
'texturedObjects': 'all',
'emptyRoom': empty_room,
'hideCategories': ['person', 'plant'],
'replaceModels': replace_doors,
'createArch': True,
'defaultModelFormat': 'obj' if dataset == 'p5dScene' else None,
'defaultSceneFormat': 'suncg' if dataset == 'p5dScene' else None
}
sim_defaults = {
'simulator': 'room_simulator',
'num_simulators': 1,
# Shared RoomSimulator and DoomSimulator params
'modalities': ['color', 'measurements'],
'outputs': ['color', 'measurements', 'rewards', 'terminals'],
'resolution': (84, 84),
'frame_skip': 1,
# RoomSimulator params (most are also Simulator.py params)
'host': 'localhost',
'log_action_trace': False,
'auto_start': True,
'collision_detection': {'mode': 'navgrid'},
'navmap': {'refineGrid': True, 'autoUpdate': True, 'allowDiagonalMoves': True, 'reverseEdgeOrder': False},
'reward_type': 'dist_time',
'observations': {'color': True, 'forces': False, 'audio': False, 'objects': False, 'depth': False},
'color_encoding': 'rgba',
'scene': {'arch_only': False, 'retexture': False, 'empty_room': False, 'dataset': 'p5dScene'},
# DoomSimulator params
'config': '', # Also in RoomSimulator but unused
'color_mode': 'GRAY',
'maps': ['MAP01'], # Also in RoomSimulator but unused
'switch_maps': False,
'game_args': '',
# task params
'task': 'room_goal',
'goal': {'roomTypes': 'any', 'select': 'random'},
'scenes_file': '../data/scenes.multiroom.csv',
'states_file': '../data/episode_states.suncg.csv.bz2',
'roomtypes_file': '../data/roomTypes.suncg.csv',
'num_episodes_per_restart': 1000,
'num_episodes_per_scene': 10,
'max_states_per_scene': 1,
'episodes_per_scene_test': 1, # DFP param
'episodes_per_scene_train': 10, # DFP param
'episode_schedule': 'train', # DFP param
'measure_fun': measures.MeasureDistDirTime(),
}
def update_dict(d, u):
if d and u:
for k, v in u.items():
if isinstance(v, collections.Mapping):
d[k] = update_dict(d.get(k, {}), v)
else:
d[k] = v
return d
def get(env_config, override_args=None, print_config=False):
simargs = copy.copy(sim_defaults)
if env_config:
env = __import__('minos.config.envs.' + env_config, fromlist=['config'])
simargs.update(env.config)
# augmentation / setting of args
s = simargs['scene']
simargs['scene'] = get_scene_params(arch_only=s.get('arch_only', None),
retexture=s.get('retexture', None),
empty_room=s.get('empty_room', None),
dataset=s.get('dataset', None))
for path in ['scenes_file', 'states_file', 'roomtypes_file']:
simargs[path] = resolve_relative_path(simargs[path])
simargs['logdir'] = os.path.join('logs', time.strftime("%Y_%m_%d_%H_%M_%S"))
update_dict(simargs, override_args)
if print_config:
pprint.pprint(simargs)
return simargs
@ngthanhtin
Copy link

Hi, your brief introduction is really helpful, but did you wrote a path finding algorithm (such as A*, BFS, DFS,...) to automatically move the agent in the world ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment