Skip to content

Commit

Permalink
Added description how to use config system, fixed missing copyright h…
Browse files Browse the repository at this point in the history
…eaders, improved example and isort CI (facebookresearch#125)

* Added description how to use config system related to facebookresearch#20.
* Added missing copyright headers
* Improve registry example to be cleaner
* Adde habitat_sim as first party lib to isort CI setup
  • Loading branch information
mathfac authored Jun 15, 2019
1 parent 1891bd8 commit 959799b
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 10 deletions.
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ jobs:
- run:
name: run isort
command: |
isort . -rc --multi-line 3 --trailing-comma --force-grid-wrap 0 --line-width 79 --combine-as -o torch -o pytest -o torchvision -o matplotlib --diff
isort . -rc --multi-line 3 --trailing-comma --force-grid-wrap 0 --line-width 79 --combine-as -o torch -o pytest -o torchvision -o matplotlib --check-only
isort . -rc --multi-line 3 --trailing-comma --force-grid-wrap 0 --line-width 79 --combine-as -o torch -o pytest -o torchvision -o matplotlib -p habitat_sim --diff
isort . -rc --multi-line 3 --trailing-comma --force-grid-wrap 0 --line-width 79 --combine-as -o torch -o pytest -o torchvision -o matplotlib -p habitat_sim --check-only
install_and_test_ubuntu:
<<: *gpu
Expand Down
103 changes: 103 additions & 0 deletions configs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
Habitat-API Configuration
==============================

Habitat-API uses [Yacs configuration system](https://github.com/rbgirshick/yacs)
with the paradigm of `your code + a YACS config for experiment E (+
external dependencies + hardware + other nuisance terms ...) =
reproducible experiment E`. Yacs advantages:
- Checks for type consistency.
- All parameters and default values are searchable in the code.
- A parameter doesn't need to be set always as each parameter has a
default value.
- Ability to freeze config to prevent unintended changes.

## Config usage
An example of how to merge default config with 2 others configs and overwrite
one parameter that could come from the command line:
```
merged_config = get_config(
config_paths=["configs/tasks/pointnav.yaml",
"configs/dataset/val.yaml"],
opts=["ENVIRONMENT.MAX_EPISODE_STEPS", steps_limit]
)
```

## Config structure
Below is the structure of config used for Habitat:
- Environment
- Task
- Sensors
- Measurements
- Simulator
- Agent
- Sensors
- Dataset

We use node names (e.g. `SENSORS: ['RGB_SENSOR', 'DEPTH_SENSOR']`) instead of list
of config nodes (e.g. `SENSORS: [{TYPE = "HabitatSimDepthSensor",
MIN_DEPTH = 0}, ...]`) to declare the Sensors attached to an Agent or Measures
enabled for the Task . With this approach, it's still easy to overwrite a
particular sensor parameter in yaml file without redefining the whole sensor
config.

## Extending the config
Example of how to extend a config outside of `habtiat-api` repository.
First, we create a config extending the default config in the code and re-use
`habitat.get_config()`:
```
import habitat
import argparse
from typing import List, Optional, Union
_C = habitat.get_config()
_C.defrost()
# Add new parameters to the config
_C.TASK.EPISODE_INFO = habitat.Config()
_C.TASK.EPISODE_INFO.TYPE = "EpisodeInfo"
_C.TASK.EPISODE_INFO.VALUE = 5
_C.TASK.MEASUREMENTS.append("EPISODE_INFO")
# New function returning extended Habitat config that should be used instead
# of habitat.get_config()
def my_get_config(
config_paths: Optional[Union[List[str], str]] = None,
opts: Optional[list] = None,
) -> habitat.Config:
CONFIG_FILE_SEPARATOR = ","
config = _C.clone()
if config_paths:
if isinstance(config_paths, str):
if CONFIG_FILE_SEPARATOR in config_paths:
config_paths = config_paths.split(CONFIG_FILE_SEPARATOR)
else:
config_paths = [config_paths]
for config_path in config_paths:
config.merge_from_file(config_path)
if opts:
config.merge_from_list(opts)
config.freeze()
return config
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"--task-config",
type=str,
default="configs/tasks/pointnav.yaml,"
"configs/datasets/pointnav/habitat_test.yaml",
)
parser.add_argument(
"opts",
default=None,
nargs=argparse.REMAINDER,
help="Modify config options from command line",
)
args = parser.parse_args()
config = my_get_config(config_paths=args.task_config, opts=args.opts)
env = habitat.Env(config)
```
5 changes: 5 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
#!/usr/bin/env python3

# Copyright (c) Facebook, Inc. and its affiliates.
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

# -*- coding: utf-8 -*-
#
# habitat-api documentation build configuration file, created by
Expand Down
15 changes: 10 additions & 5 deletions examples/register_new_sensors_and_measures.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
#!/usr/bin/env python3

# Copyright (c) Facebook, Inc. and its affiliates.
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

from typing import Any

import numpy as np
from gym import spaces

import habitat
from habitat.config import Config as CN


# Define the measure and register it with habitat
# By default, the things are registered with the class name
@habitat.registry.register_measure
class EpisodeInfo(habitat.Measure):
def __init__(self, sim, config):
def __init__(self, sim, config, **kwargs: Any):
# This measure only needs the config
self._config = config

Expand All @@ -38,7 +43,7 @@ def update_metric(self, episode, action):
# For the sensor, we will register it with a custom name
@habitat.registry.register_sensor(name="my_supercool_sensor")
class AgentPositionSensor(habitat.Sensor):
def __init__(self, sim, config):
def __init__(self, sim, config, **kwargs: Any):
super().__init__(config=config)

self._sim = sim
Expand Down Expand Up @@ -73,7 +78,7 @@ def main():
config.defrost()

# Add things to the config to for the measure
config.TASK.EPISODE_INFO = CN()
config.TASK.EPISODE_INFO = habitat.Config()
# The type field is used to look-up the measure in the registry.
# By default, the things are registered with the class name
config.TASK.EPISODE_INFO.TYPE = "EpisodeInfo"
Expand All @@ -82,7 +87,7 @@ def main():
config.TASK.MEASUREMENTS.append("EPISODE_INFO")

# Now define the config for the sensor
config.TASK.AGENT_POSITION_SENSOR = CN()
config.TASK.AGENT_POSITION_SENSOR = habitat.Config()
# Use the custom name
config.TASK.AGENT_POSITION_SENSOR.TYPE = "my_supercool_sensor"
config.TASK.AGENT_POSITION_SENSOR.ANSWER_TO_LIFE = 42
Expand Down
6 changes: 6 additions & 0 deletions habitat/datasets/pointnav/pointnav_generator.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
#!/usr/bin/env python3

# Copyright (c) Facebook, Inc. and its affiliates.
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

from typing import Optional

import numpy as np
Expand Down
6 changes: 6 additions & 0 deletions habitat/datasets/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
#!/usr/bin/env python3

# Copyright (c) Facebook, Inc. and its affiliates.
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

from typing import List

from habitat.core.logging import logger
Expand Down
3 changes: 2 additions & 1 deletion habitat_baselines/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,5 @@ Set argument `--task-config` to `tasks/pointnav_mp3d.yaml` for training on [Matt

**SLAM based**

- [Handcrafted agent baseline adopted from the paper "Benchmarking Classic and Learned Navigation in Complex 3D Environments"](habitat_baselines/slambased/README.md)
- [Handcrafted agent baseline](slambased/README.md) adopted from the paper
"Benchmarking Classic and Learned Navigation in Complex 3D Environments".
6 changes: 6 additions & 0 deletions habitat_baselines/agents/slam_agents.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
#!/usr/bin/env python3

# Copyright (c) Facebook, Inc. and its affiliates.
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

import argparse
import os
import random
Expand Down
6 changes: 5 additions & 1 deletion test/test_demo_notebook.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import os
#!/usr/bin/env python3

# Copyright (c) Facebook, Inc. and its affiliates.
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

import pytest

Expand Down
6 changes: 5 additions & 1 deletion test/test_relative_camera.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import os
#!/usr/bin/env python3

# Copyright (c) Facebook, Inc. and its affiliates.
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

import pytest

Expand Down

0 comments on commit 959799b

Please sign in to comment.