diff --git a/README.md b/README.md index a2a7f475bc59cb7ca5348d93a5c74c0b33bda795..c8d526507acffaa3e850b21d3f7a6c56fca16f18 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ <p align="center"> - <img width = "50%" src='docs/img/habitat_logo_with_text_horizontal_blue.png' /> + <img width = "50%" src='res/img/habitat_logo_with_text_horizontal_blue.png' /> </p> -------------------------------------------------------------------------------- @@ -13,7 +13,7 @@ defining embodied AI tasks (e.g. navigation, instruction following, question ans Habitat-API currently uses [`Habitat-Sim`](https://github.com/facebookresearch/habitat-sim) as the core simulator, but is designed with a modular abstraction for the simulator backend to maintain compatibility over multiple simulators. <p align="center"> - <img src="docs/img/habitat_compressed.gif" height="400"> + <img src="res/img/habitat_compressed.gif" height="400"> </p> --- @@ -49,17 +49,21 @@ If you use the Habitat platform in your research, please cite the following [tec ## Installation -1. Clone the github repository and install using the commands below. Note that python>=3.6 is required for working with habitat-api. All the development and testing was done using python3.6. Please use 3.6 to avoid possible issues. -```bash -cd habitat-api -pip install -e . -``` -The command above will install only habitat core API. To include habitat_baselines along with all additional requirements, use the command below instead: -```bash -cd habitat-api -pip install -r requirements.txt -python setup.py develop --all # install habitat and habitat_baselines -``` +1. Clone the github repository and install habitat-api using the commands below. Note that python>=3.6 is required for working with habitat-api. All the development and testing was done using python3.6. Please use 3.6 to avoid possible issues. + + ```bash + cd habitat-api + pip install -e . + ``` + + The command above will install only habitat core API. To include habitat_baselines along with all additional requirements, use the command below instead: + + ```bash + cd habitat-api + pip install -r requirements.txt + python setup.py develop --all # install habitat and habitat_baselines + ``` + 2. Install `habitat-sim` from [github repo](https://github.com/facebookresearch/habitat-sim). 3. Download the [test scenes data](http://dl.fbaipublicfiles.com/habitat/habitat-test-scenes.zip) and extract `data` folder in zip to `habitat-api/data/` where `habitat-api/` is the github repository folder. @@ -117,7 +121,7 @@ An important objective of Habitat-API is to make it easy for users to set up a v * `Episode`: a class for episode specification that includes the initial position and orientation of an Agent, a scene id, a goal position and optionally shortest paths to the goal. An episode is a description of one task instance for the agent. <p align="center"> - <img src='docs/img/habitat-api_structure.png' alt="teaser results" width="100%"/> + <img src='res/img/habitat-api_structure.png' alt="teaser results" width="100%"/> <p align="center"><i>Architecture of Habitat-API</i></p> </p> @@ -164,3 +168,4 @@ Habitat-API is MIT licensed. See the LICENSE file for details. ## References 1. [Habitat: A Platform for Embodied AI Research](https://arxiv.org/abs/1904.01201). Manolis Savva, Abhishek Kadian, Oleksandr Maksymets, Yili Zhao, Erik Wijmans, Bhavana Jain, Julian Straub, Jia Liu, Vladlen Koltun, Jitendra Malik, Devi Parikh, Dhruv Batra. Tech report, arXiv:1904.01201, 2019. + diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..d0c3cbf1020d5c292abdedf27627c6abe25e2293 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a35133a46ea4950deb1a684dc92f3d908883b496 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,10 @@ +# docs + +To generate docs follow the below steps: + +1. `pip install -r requirements.txt` +1. Install requirements for habitat-api from the corresponding requirements.txt +1. `make html` + +Running the above commands will create a `build` folder containing html files for the generated documentation. + diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..4600f81ca02e1e2095e45a8bdc963c9f11f99ff8 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,3 @@ +recommonmark==0.5.0 +sphinx +sphinx_rtd_theme==0.4.3 diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000000000000000000000000000000000000..9388f6d91270d1009dace17e86cf297462ec51f0 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# habitat-api documentation build configuration file, created by +# sphinx-quickstart on Wed Jun 07 09:33:48 2019. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. + +import sphinx_rtd_theme +import recommonmark +from recommonmark.transform import AutoStructify + + +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.doctest", + "sphinx.ext.todo", + "sphinx.ext.coverage", + "sphinx.ext.mathjax", + "sphinx.ext.ifconfig", + "sphinx.ext.viewcode", + "sphinx.ext.napoleon", + "sphinx.ext.intersphinx", + "recommonmark", +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +source_suffix = [".rst", ".md"] +# source_suffix = '.rst' + +# The master toctree document. +master_doc = "index" + +# General information about the project. +project = "habitat-api" +copyright = "2019, Facebook AI Research" +author = "Facebook AI Research" + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +with open("../../habitat/version.py") as f: + lines = f.readlines() + + # The short X.Y version. + version = lines[-1].strip().split()[-1][1:-1] + + # The full version, including alpha/beta/rc tags. + release = version + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "sphinx_rtd_theme" +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# This is required for the alabaster theme +# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars +html_sidebars = { + "**": [ + "relations.html", # needs 'show_related': True theme option to display + "searchbox.html", + ] +} + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = "habitatdoc" + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ( + master_doc, + "habitat.tex", + "habitat documentation", + "Facebook AI Research", + "manual", + ) +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [(master_doc, "habitat", "habitat documentation", [author], 1)] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + master_doc, + "habitat", + "habitat Documentation", + author, + "habitat", + "One line description of project.", + "Miscellaneous", + ) +] + +github_doc_root = ( + f"https://github.com/facebookresearch/habitat-api/blob/{version}/" +) + +# At the bottom of conf.py +def setup(app): + app.add_config_value( + "recommonmark_config", + { + "url_resolver": lambda url: github_doc_root + url, + "auto_toc_tree_section": "Contents", + }, + True, + ) + app.add_transform(AutoStructify) diff --git a/docs/source/core/agent.rst b/docs/source/core/agent.rst new file mode 100644 index 0000000000000000000000000000000000000000..5663691cfb5e89574d94e6142bacd9127134f87e --- /dev/null +++ b/docs/source/core/agent.rst @@ -0,0 +1,5 @@ +habitat.Agent +================= + +.. automodule:: habitat.core.agent + :members: diff --git a/docs/source/core/benchmark.rst b/docs/source/core/benchmark.rst new file mode 100644 index 0000000000000000000000000000000000000000..5f4cef9619a901ed99624c569ff9a9075202b0ba --- /dev/null +++ b/docs/source/core/benchmark.rst @@ -0,0 +1,5 @@ +habitat.Benchmark +================= + +.. automodule:: habitat.core.benchmark + :members: diff --git a/docs/source/core/dataset.rst b/docs/source/core/dataset.rst new file mode 100644 index 0000000000000000000000000000000000000000..5fe8bfff7286b9ac609faa951b24b7133d526104 --- /dev/null +++ b/docs/source/core/dataset.rst @@ -0,0 +1,5 @@ +habitat.core.dataset +==================== + +.. automodule:: habitat.core.dataset + :members: diff --git a/docs/source/core/embodied_task.rst b/docs/source/core/embodied_task.rst new file mode 100644 index 0000000000000000000000000000000000000000..f85534829191e559c5bbc69f2ba8af1039072a0c --- /dev/null +++ b/docs/source/core/embodied_task.rst @@ -0,0 +1,5 @@ +habitat.core.embodied_task +=========================== + +.. automodule:: habitat.core.embodied_task + :members: diff --git a/docs/source/core/env.rst b/docs/source/core/env.rst new file mode 100644 index 0000000000000000000000000000000000000000..b3d48ea634d8acb03b4e0f22f64178a89152814e --- /dev/null +++ b/docs/source/core/env.rst @@ -0,0 +1,5 @@ +habitat.core.env +================= + +.. automodule:: habitat.core.env + :members: diff --git a/docs/source/core/simulator.rst b/docs/source/core/simulator.rst new file mode 100644 index 0000000000000000000000000000000000000000..a35640b14725e739a7622719af405ba16be02cf8 --- /dev/null +++ b/docs/source/core/simulator.rst @@ -0,0 +1,5 @@ +habitat.core.simulator +======================= + +.. automodule:: habitat.core.simulator + :members: diff --git a/docs/source/core/vector_env.rst b/docs/source/core/vector_env.rst new file mode 100644 index 0000000000000000000000000000000000000000..178175b52e0a98ee68629c5f7e955f93583fcf7e --- /dev/null +++ b/docs/source/core/vector_env.rst @@ -0,0 +1,5 @@ +habitat.core.vector_env +======================= + +.. automodule:: habitat.core.vector_env + :members: diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..ec7358d30c34691e40f0569ddefe3a0b634b7059 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,36 @@ +.. habitat-api documentation master file, created by + sphinx-quickstart on Tue Jun 4 13:03:57 2019. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +:github_url: https://github.com/facebookresearch/habitat-api + +habitat-api documentation +======================================= + +A modular high-level library to train embodied AI agents across a variety of tasks, environments, and simulators. + +.. toctree:: + :maxdepth: 1 + :caption: Tutorials + + tutorials/quickstart + +.. toctree:: + :maxdepth: 1 + :caption: Package Reference + + habitat.core.env <core/env> + habitat.core.embodied_task <core/embodied_task> + habitat.core.dataset <core/dataset> + habitat.core.simulator <core/simulator> + habitat.core.vector_env <core/vector_env> + habitat.Agent <core/agent> + habitat.Benchmark <core/benchmark> + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` diff --git a/docs/source/tutorials/quickstart.md b/docs/source/tutorials/quickstart.md new file mode 100644 index 0000000000000000000000000000000000000000..fc083300dddcea97b9551abba6b39e3defffc410 --- /dev/null +++ b/docs/source/tutorials/quickstart.md @@ -0,0 +1,109 @@ +# Quickstart + +In this quickstart we will briefly introduce the habitat stack using which we will setup the pointnav task and step around in the environment. + +## Habitat + +Habitat is a platform for embodied AI research that consists of: +1. **Habitat-Sim**: A flexible, high-performance 3D simulator with configurable agents, multiple sensors, and generic 3D dataset handling (with built-in support for [MatterPort3D](https://niessner.github.io/Matterport/), [Gibson](http://gibsonenv.stanford.edu/database/) and other datasets). [[github-repo](https://github.com/facebookresearch/habitat-sim)] + +1. **Habitat-API**: A modular high-level library for end-to-end development in embodied AI -- defining embodied AI tasks (e.g. navigation, instruction following, question answering), configuring embodied agents (physical form, sensors, capabilities), training these agents (via imitation or reinforcement learning, or no learning at all as in classical SLAM), and benchmarking their performance on the defined tasks using standard metrics. [[github-repo](https://github.com/facebookresearch/habitat-api)] + +For installing Habitat-Sim and Habitat-API follow instructions [here](https://github.com/facebookresearch/habitat-api#installation). + +## Example + +In this example we will setup a PointNav task in which the agent is tasked to go from a source location to a target location. For this example the agent will be you (the user). You will be able to step around in an environment using keys. + +For running this example both Habitat-Sim and Habitat-API should be installed successfully. The data for scene should also be downloaded (steps to do this are provided in the [installation instructions](https://github.com/facebookresearch/habitat-api#installation) of Habitat-API). Running the code below also requires installation of cv2 which you can install using: `pip install opencv-python`. + +```python +import habitat +import cv2 + + +FORWARD_KEY="w" +LEFT_KEY="a" +RIGHT_KEY="d" +FINISH="f" + + +def transform_rgb_bgr(image): + return image[:, :, [2, 1, 0]] + + +def example(): + env = habitat.Env( + config=habitat.get_config("configs/tasks/pointnav.yaml") + ) + + print("Environment creation successful") + observations = env.reset() + print("Destination, distance: {:3f}, theta(radians): {:.2f}".format( + observations["pointgoal"][0], observations["pointgoal"][1])) + cv2.imshow("RGB", transform_rgb_bgr(observations["rgb"])) + + print("Agent stepping around inside environment.") + + count_steps = 0 + while not env.episode_over: + keystroke = cv2.waitKey(0) + + if keystroke == ord(FORWARD_KEY): + action = 0 + print("action: FORWARD") + elif keystroke == ord(LEFT_KEY): + action = 1 + print("action: LEFT") + elif keystroke == ord(RIGHT_KEY): + action = 2 + print("action: RIGHT") + elif keystroke == ord(FINISH): + action = 3 + print("action: FINISH") + else: + print("INVALID KEY") + continue + + observations = env.step(action) + count_steps += 1 + + print("Destination, distance: {:3f}, theta(radians): {:.2f}".format( + observations["pointgoal"][0], observations["pointgoal"][1])) + cv2.imshow("RGB", transform_rgb_bgr(observations["rgb"])) + + print("Episode finished after {} steps.".format(count_steps)) + + if action == 3 and observations["pointgoal"][0] < 0.2: + print("you successfully navigated to destination point") + else: + print("your navigation was unsuccessful") + + +if __name__ == "__main__": + example() +``` + +Running the above code will initialize an agent inside an environment, you can move around in the environment using `w`, `a`, `d`, `f` keys. On the terminal a destination vector in polar format will be printed with distance to goal and angle to goal. Once you are withing 0.2m of goal you can press the `f` key to `STOP` and finish the episode successfully. If your finishing distance to goal is > 0.2m or if you spend more than 500 steps in the environment your episode will be unsuccessful. + +Below is a demo of what the example output will look like: + +<p align="center"> + <img src="https://i.imgur.com/5EaQUnf.png" height="400"> +</p> + +For more examples refer to [Habitat-API examples](https://github.com/facebookresearch/habitat-sim/tree/master/examples) and [Habitat-Sim examples](https://github.com/facebookresearch/habitat-sim/tree/master/examples). + +## Citation + +If you use habitat in your work, please cite: + +```text +@article{habitat19arxiv, + title = {Habitat: A Platform for Embodied AI Research}, + author = {{Manolis Savva*}, {Abhishek Kadian*}, {Oleksandr Maksymets*}, Yili Zhao, Erik Wijmans, Bhavana Jain, Julian Straub, Jia Liu, Vladlen Koltun, Jitendra Malik, Devi Parikh and Dhruv Batra}, + journal = {arXiv preprint arXiv:1904.01201}, + year = {2019} +} +``` + diff --git a/examples/pointnav_episode_gen_example.py b/examples/pointnav_episode_gen_example.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/habitat/config/default.py b/habitat/config/default.py index 6dc20c4031c7cc9e59a58d87da83398020f52324..3782c5ffd16baded04fbd2a3e9f8e783283410a7 100644 --- a/habitat/config/default.py +++ b/habitat/config/default.py @@ -168,8 +168,7 @@ def get_config( config_paths: Optional[Union[List[str], str]] = None, opts: Optional[list] = None, ) -> CN: - """ - Create a unified config with default values overwritten by values from + r"""Create a unified config with default values overwritten by values from `config_paths` and overwritten by options from `opts`. Args: config_paths: List of config paths or string that contains comma diff --git a/habitat/core/agent.py b/habitat/core/agent.py index bb39009207fcfd8f5895e16030da7f4051aac91e..0b8f299b61dd5b2051811bba3614663c3811202a 100644 --- a/habitat/core/agent.py +++ b/habitat/core/agent.py @@ -3,32 +3,32 @@ # 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. +r"""Base implementation of agent inside habitat. To build agents inside habitat +the user should subclass ``habitat.Agent`` and implement the ``step()`` +and ``reset()`` methods. +""" from habitat.core.simulator import Observations class Agent: - """Abstract class for defining agents which act inside Env. This abstract - class standardizes agents to allow seamless benchmarking. To implement an - agent the user has to implement two methods: - - reset - act + r"""Abstract class for defining agents which act inside Env. This abstract + class standardizes agents to allow seamless benchmarking. """ def reset(self) -> None: - """Called before starting a new episode in environment. + r"""Called before starting a new episode in environment. """ raise NotImplementedError def act(self, observations: Observations) -> int: - """ + r""" Args: observations: observations coming in from environment to be used by agent to decide action. Returns: - action to be taken inside the environment + action to be taken inside the environment. """ raise NotImplementedError diff --git a/habitat/core/benchmark.py b/habitat/core/benchmark.py index 037b6155be2c78b229f0e0bf0fbc06a5d5871753..4c20b6b33d35d784cc1145d33f111eabf6c20fac 100644 --- a/habitat/core/benchmark.py +++ b/habitat/core/benchmark.py @@ -3,6 +3,11 @@ # 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. +r"""Implements evaluation of ``habitat.Agent`` inside ``habitat.Env``. +``habitat.Benchmark`` creates a ``habitat.Env`` which is specified through +the ``config_env`` parameter in constructor. The evaluation is task agnostic +and is implemented through metrics defined for ``habitat.EmbodiedTask``. +""" from collections import defaultdict from typing import Dict, Optional @@ -13,7 +18,7 @@ from habitat.core.env import Env class Benchmark: - """Benchmark for evaluating agents in environments. + r"""Benchmark for evaluating agents in environments. Args: @@ -28,7 +33,7 @@ class Benchmark: def evaluate( self, agent: Agent, num_episodes: Optional[int] = None ) -> Dict[str, float]: - """ + r""" Args: agent: agent to be evaluated in environment. num_episodes: count of number of episodes for which the evaluation diff --git a/habitat/core/dataset.py b/habitat/core/dataset.py index 7cba9f63304c284f587ff26e65af4be66b91b308..713cb63ab556c9968e026be281c15cd26dcf2812 100644 --- a/habitat/core/dataset.py +++ b/habitat/core/dataset.py @@ -3,7 +3,11 @@ # 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. - +r"""Implements dataset functionality to be used ``habitat.EmbodiedTask``. +``habitat.core.dataset`` abstracts over a collection of +``habitat.core.Episode``. Each episode consists of a single instantiation +of a ``habitat.Agent`` inside ``habitat.Env``. +""" import copy import json from typing import Callable, Dict, Generic, List, Optional, Type, TypeVar @@ -16,12 +20,12 @@ from habitat.core.utils import not_none_validator @attr.s(auto_attribs=True, kw_only=True) class Episode: - """Base class for episode specification that includes initial position and + r"""Base class for episode specification that includes initial position and rotation of agent, scene id, episode. This information is provided by - a Dataset instance. + a ``Dataset`` instance. Args: - episode_id: id of episode in the dataset, usually episode number + episode_id: id of episode in the dataset, usually episode number. scene_id: id of scene in dataset. start_position: list of length 3 for cartesian coordinates (x, y, z). @@ -47,41 +51,41 @@ T = TypeVar("T", Episode, Type[Episode]) class Dataset(Generic[T]): - """Base class for dataset specification. + r"""Base class for dataset specification. Attributes: - episodes: list of episodes containing instance information + episodes: list of episodes containing instance information. """ episodes: List[T] @property def scene_ids(self) -> List[str]: - """ + r""" Returns: - unique scene ids present in the dataset + unique scene ids present in the dataset. """ return sorted(list({episode.scene_id for episode in self.episodes})) def get_scene_episodes(self, scene_id: str) -> List[T]: - """ + r""" Args: - scene_id: id of scene in scene dataset + scene_id: id of scene in scene dataset. Returns: - list of episodes for the scene_id + list of episodes for the ``scene_id``. """ return list( filter(lambda x: x.scene_id == scene_id, iter(self.episodes)) ) def get_episodes(self, indexes: List[int]) -> List[T]: - """ + r""" Args: - indexes: episode indices in dataset + indexes: episode indices in dataset. Returns: - list of episodes corresponding to indexes + list of episodes corresponding to indexes. """ return [self.episodes[episode_id] for episode_id in indexes] @@ -96,26 +100,29 @@ class Dataset(Generic[T]): def from_json( self, json_str: str, scenes_dir: Optional[str] = None ) -> None: - """ - Parses passed JSON string and creates dataset based on that. - Function is used as deserialization method for Dataset. + r""" + Creates dataset from ``json_str``. Directory containing relevant + graphical assets of scenes is passed through ``scenes_dir``. + Args: - json_str: JSON dump of Dataset instance. - scenes_dir: Path to directory with scenes assets such as *.glb - files. + json_str: JSON string containing episodes information. + scenes_dir: directory containing graphical assets relevant + for episodes present in ``json_str``. """ raise NotImplementedError def filter_episodes( self, filter_fn: Callable[[Episode], bool] ) -> "Dataset": - """ - Returns a new dataset with only the filtered episodes from the original - dataset. + r""" + Returns a new dataset with only the filtered episodes from the + original dataset. + Args: - filter_fn: Function used to filter the episodes. + filter_fn: function used to filter the episodes. + Returns: - The new dataset. + the new dataset. """ new_episodes = [] for episode in self.episodes: @@ -134,32 +141,34 @@ class Dataset(Generic[T]): sort_by_episode_id: bool = False, allow_uneven_splits: bool = False, ) -> List["Dataset"]: - """ - Returns a list of new datasets, each with a subset of the original + r"""Returns a list of new datasets, each with a subset of the original episodes. All splits will have the same number of episodes, but no episodes will be duplicated. + Args: - num_splits: The number of splits to create. - episodes_per_split: If provided, each split will have up to + num_splits: the number of splits to create. + episodes_per_split: if provided, each split will have up to this many episodes. If it is not provided, each dataset will - have len(original_dataset.episodes) // num_splits episodes. If - max_episodes_per_split is provided and is larger than this - value, it will be capped to this value. - remove_unused_episodes: Once the splits are created, the extra + have ``len(original_dataset.episodes) // num_splits`` + episodes. If max_episodes_per_split is provided and is + larger than this value, it will be capped to this value. + remove_unused_episodes: once the splits are created, the extra episodes will be destroyed from the original dataset. This saves memory for large datasets. - collate_scene_ids: If true, episodes with the same scene id are - next to each other. This saves on overhead of switching between - scenes, but means multiple sequential episodes will be related - to each other because they will be in the same scene. - sort_by_episode_id: If true, sequences are sorted by their episode + collate_scene_ids: if true, episodes with the same scene id are + next to each other. This saves on overhead of switching + between scenes, but means multiple sequential episodes will + be related to each other because they will be in the + same scene. + sort_by_episode_id: if true, sequences are sorted by their episode ID in the returned splits. - allow_uneven_splits: If true, the last split can be shorter than + allow_uneven_splits: if true, the last split can be shorter than the others. This is especially useful for splitting over validation/test datasets in order to make sure that all episodes are copied but none are duplicated. + Returns: - A list of new datasets, each with their own subset of episodes. + a list of new datasets, each with their own subset of episodes. """ assert ( len(self.episodes) >= num_splits diff --git a/habitat/core/embodied_task.py b/habitat/core/embodied_task.py index 775c1c09b95f161ddafe475248d6a7c897d5819d..d9e063b52d6b2dbd0dd9f8839adc856062f58dbc 100644 --- a/habitat/core/embodied_task.py +++ b/habitat/core/embodied_task.py @@ -3,6 +3,9 @@ # 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. +r"""Implements tasks and measurements needed for training and benchmarking of +``habitat.Agent`` inside ``habitat.Env``. +""" from collections import OrderedDict from typing import Any, Dict, List, Optional, Type @@ -13,7 +16,7 @@ from habitat.core.simulator import SensorSuite, Simulator class Measure: - """Represents a measure that provides measurement on top of environment + r"""Represents a measure that provides measurement on top of environment and task. This can be used for tracking statistics when running experiments. The user of this class needs to implement the reset_metric and update_metric method and the user is also required to set the below @@ -21,8 +24,8 @@ class Measure: Attributes: uuid: universally unique id. - _metric: metric for the Measure, this has to be updated with each - step call on environment. + _metric: metric for the ``Measure``, this has to be updated with each + ``step`` call on ``habitat.Env``. """ def __init__(self, *args: Any, **kwargs: Any) -> None: @@ -33,28 +36,29 @@ class Measure: raise NotImplementedError def reset_metric(self, *args: Any, **kwargs: Any) -> None: - """Reset _metric, this method is called from Env on each reset. + r"""Reset ``_metric``, this method is called from ``Env`` on each reset. """ raise NotImplementedError def update_metric(self, *args: Any, **kwargs: Any) -> None: - """Update _metric, this method is called from Env on each step. + r"""Update ``_metric``, this method is called from ``Env`` on each + ``step``. """ raise NotImplementedError def get_metric(self): - """ + r""" Returns: - the current metric for Measure. + the current metric for ``Measure``. """ return self._metric class Metrics(dict): - """Dictionary containing measurements. + r"""Dictionary containing measurements. Args: - measures: list of Measures whose metrics are fetched and packaged. + measures: list of ``Measure`` whose metrics are fetched and packaged. """ def __init__(self, measures: Dict[str, Measure]) -> None: @@ -65,12 +69,12 @@ class Metrics(dict): class Measurements: - """Represents a set of Measures, with each Measure being identified + r"""Represents a set of Measures, with each ``Measure`` being identified through a unique id. Args: - measures: list containing Measures, uuid of each - Measure must be unique. + measures: list containing ``Measure``, uuid of each + ``Measure`` must be unique. """ measures: Dict[str, Measure] @@ -92,7 +96,7 @@ class Measurements: measure.update_metric(*args, **kwargs) def get_metrics(self) -> Metrics: - """ + r""" Returns: collect measurement from all Measures and return it packaged inside Metrics. @@ -101,9 +105,8 @@ class Measurements: class EmbodiedTask: - """Base class for embodied tasks. When subclassing the user has - to define the attributes listed below. When subclassing the user has to - define the attributes measurements and sensor_suite. + r"""Base class for embodied tasks. When subclassing the user has to + define the attributes ``measurements`` and ``sensor_suite``. Args: config: config for the task. @@ -131,12 +134,13 @@ class EmbodiedTask: def overwrite_sim_config( self, sim_config: Config, episode: Type[Episode] ) -> Config: - """ + r""" Args: sim_config: config for simulator. episode: current episode. Returns: - update config merging information from sim_config and episode. + update config merging information from ``sim_config`` and + ``episode``. """ raise NotImplementedError diff --git a/habitat/core/env.py b/habitat/core/env.py index 874e69c25148f4100b1675a622f256c378d18c1f..eaf72b43164ad581b10ce1995fbc8fd1150dc028 100644 --- a/habitat/core/env.py +++ b/habitat/core/env.py @@ -21,23 +21,23 @@ from habitat.tasks import make_task class Env: - """Fundamental environment class for habitat. All the information needed - for working on embodied tasks with simulator is abstracted inside + r"""Fundamental environment class for ``habitat``. All the information + needed for working on embodied tasks with simulator is abstracted inside Env. Acts as a base for other derived environment classes. Env consists - of three major components: dataset (episodes), simulator and task and - connects all the three components together. + of three major components: ``dataset`` (``episodes``), ``simulator`` and + ``task`` and connects all the three components together. Args: config: config for the environment. Should contain id for simulator and - task_name which are passed into make_sim and make_task. + ``task_name`` which are passed into ``make_sim`` and ``make_task``. dataset: reference to dataset for task instance level information. - Can be defined as None in which case _episodes should be populated - from outside. + Can be defined as ``None`` in which case ``_episodes`` should be + populated from outside. Attributes: - observation_space: SpaceDict object corresponding to sensor in sim + observation_space: ``SpaceDict`` object corresponding to sensor in sim and task. - action_space: gym.space object corresponding to valid actions. + action_space: ``gym.space`` object corresponding to valid actions. """ observation_space: SpaceDict @@ -59,7 +59,7 @@ class Env: ) -> None: assert config.is_frozen(), ( "Freeze the config before creating the " - "environment, use config.freeze()" + "environment, use config.freeze()." ) self._config = config self._dataset = dataset @@ -72,9 +72,9 @@ class Env: # load the first scene if dataset is present if self._dataset: - assert len(self._dataset.episodes) > 0, ( - "dataset should have " "non-empty episodes list" - ) + assert ( + len(self._dataset.episodes) > 0 + ), "dataset should have non-empty episodes list" self._config.defrost() self._config.SIMULATOR.SCENE = self._dataset.episodes[0].scene_id self._config.freeze() @@ -167,10 +167,10 @@ class Env: self._episode_over = False def reset(self) -> Observations: - """Resets the environments and returns the initial observations. + r"""Resets the environments and returns the initial observations. Returns: - Initial observations from the environment + initial observations from the environment. """ self._reset_stats() @@ -203,22 +203,22 @@ class Env: self._episode_over = True def step(self, action: int) -> Observations: - """Perform an action in the environment and return observations + r"""Perform an action in the environment and return observations. Args: - action: action (belonging to action_space) to be performed inside - the environment. + action: action (belonging to ``action_space``) to be performed + inside the environment. Returns: observations after taking action in environment. """ - assert self._episode_start_time is not None, ( - "Cannot call step " "before calling reset" - ) - assert self._episode_over is False, ( - "Episode over, call reset " "before calling step" - ) + assert ( + self._episode_start_time is not None + ), "Cannot call step before calling reset" + assert ( + self._episode_over is False + ), "Episode over, call reset before calling step" observations = self._sim.step(action) observations.update( @@ -257,22 +257,16 @@ class Env: class RLEnv(gym.Env): - """Reinforcement Learning (RL) environment class which subclasses gym.Env. + r"""Reinforcement Learning (RL) environment class which subclasses gym.Env. This is a wrapper over habitat.Env for RL users. To create custom RL environments users should subclass RLEnv and define the following methods: + ``get_reward_range``, ``get_reward``, ``get_done``, ``get_info``. - get_reward_range - get_reward - get_done - get_info - - As this is a subclass of gym.Env, it implements - reset - step + As this is a subclass of ``gym.Env``, it implements ``reset`` and ``step``. Args: - config: config to construct habitat.Env. - dataset: dataset to construct habtiat.Env. + config: config to construct ``habitat.Env``. + dataset: dataset to construct ``habtiat.Env``. """ _env: Env @@ -301,19 +295,19 @@ class RLEnv(gym.Env): return self._env.reset() def get_reward_range(self): - """Get min, max range of reward + r"""Get min, max range of reward. Returns: - [min, max] range of reward + [min, max] range of reward. """ raise NotImplementedError def get_reward(self, observations: Observations) -> Any: - """Returns reward after action has been performed. This method + r"""Returns reward after action has been performed. This method is called inside the step method. Args: - observations: observations from simulator and task + observations: observations from simulator and task. Returns: reward after performing the last action. @@ -321,11 +315,11 @@ class RLEnv(gym.Env): raise NotImplementedError def get_done(self, observations: Observations) -> bool: - """Returns boolean indicating whether episode is done after performing + r"""Returns boolean indicating whether episode is done after performing the last action. This method is called inside the step method. Args: - observations: observations from simulator and task + observations: observations from simulator and task. Returns: done boolean after performing the last action. @@ -333,25 +327,25 @@ class RLEnv(gym.Env): raise NotImplementedError def get_info(self, observations) -> Dict[Any, Any]: - """ + r""" Args: - observations: observations from simulator and task + observations: observations from simulator and task. Returns: - info after performing the last action + info after performing the last action. """ raise NotImplementedError def step(self, action: int) -> Tuple[Observations, Any, bool, dict]: - """Perform an action in the environment and return - (observations, reward, done, info) + r"""Perform an action in the environment and return + ``(observations, reward, done, info)``. Args: - action: action (belonging to action_space) to be performed inside - the environment. + action: action (belonging to ``action_space``) to be performed + inside the environment. Returns: - (observations, reward, done, info) + ``(observations, reward, done, info)``. """ observations = self._env.step(action) diff --git a/habitat/core/registry.py b/habitat/core/registry.py index 78e71dd4bae76f54546cd72ca7db088fdd7b4046..b77ccb4af5fc62b55051886d14a0ea22dcaf53ca 100644 --- a/habitat/core/registry.py +++ b/habitat/core/registry.py @@ -4,10 +4,9 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -""" -Registry is central source of truth in Habitat. -Shamelessly taken from Pythia, it is inspired from Redux's -concept of global store, Registry maintains mappings of various information +r"""Registry is central source of truth in Habitat. +Taken from Pythia, it is inspired from Redux's +concept of global store. Registry maintains mappings of various information to unique keys. Special functions in registry can be used as decorators to register different kind of classes. diff --git a/habitat/core/simulator.py b/habitat/core/simulator.py index 15f8c6d09165b327b4fe57053498251792fbd7d7..e3325e47f7538c286d0557c1bbe88538cb20d78e 100644 --- a/habitat/core/simulator.py +++ b/habitat/core/simulator.py @@ -15,7 +15,7 @@ from habitat.config import Config class SensorTypes(Enum): - """Enumeration of types of sensors. + r"""Enumeration of types of sensors. """ NULL = 0 @@ -34,7 +34,7 @@ class SensorTypes(Enum): class Sensor: - """Represents a sensor that provides data from the environment to agent. + r"""Represents a sensor that provides data from the environment to agent. The user of this class needs to implement the get_observation method and the user is also required to set the below attributes: @@ -42,8 +42,8 @@ class Sensor: uuid: universally unique id. sensor_type: type of Sensor, use SensorTypes enum if your sensor comes under one of it's categories. - observation_space: gym.Space object corresponding to observation of - sensor + observation_space: ``gym.Space`` object corresponding to observation of + sensor. """ uuid: str @@ -67,15 +67,15 @@ class Sensor: raise NotImplementedError def get_observation(self, *args: Any, **kwargs: Any) -> Any: - """ + r""" Returns: - Current observation for Sensor. + current observation for Sensor. """ raise NotImplementedError class Observations(dict): - """Dictionary containing sensor observations + r"""Dictionary containing sensor observations Args: sensors: list of sensors whose observations are fetched and packaged. @@ -143,7 +143,7 @@ class SemanticSensor(Sensor): class SensorSuite: - """Represents a set of sensors, with each sensor being identified + r"""Represents a set of sensors, with each sensor being identified through a unique id. Args: @@ -169,7 +169,7 @@ class SensorSuite: return self.sensors[uuid] def get_observations(self, *args: Any, **kwargs: Any) -> Observations: - """ + r""" Returns: collect data from all sensors and return it packaged inside Observation. @@ -202,16 +202,8 @@ class ShortestPathPoint: class Simulator: - """Basic simulator class for habitat. New simulators to be added to habtiat - must derive from this class and implement the below methods: - reset - step - seed - reconfigure - geodesic_distance - sample_navigable_point - action_space_shortest_path - close + r"""Basic simulator class for habitat. New simulators to be added to habtiat + must derive from this class and implement the abstarct methods. """ @property @@ -227,15 +219,15 @@ class Simulator: raise NotImplementedError def reset(self) -> Observations: - """Resets the simulator and returns the initial observations. + r"""resets the simulator and returns the initial observations. Returns: - Initial observations from simulator. + initial observations from simulator. """ raise NotImplementedError def step(self, action: int) -> Observations: - """Perform an action in the simulator and return observations. + r"""Perform an action in the simulator and return observations. Args: action: action to be performed inside the simulator. @@ -254,11 +246,11 @@ class Simulator: def geodesic_distance( self, position_a: List[float], position_b: List[float] ) -> float: - """Calculates geodesic distance between two points. + r"""Calculates geodesic distance between two points. Args: - position_a: coordinates of first point - position_b: coordinates of second point + position_a: coordinates of first point. + position_b: coordinates of second point. Returns: the geodesic distance in the cartesian space between points @@ -268,12 +260,12 @@ class Simulator: raise NotImplementedError def get_agent_state(self, agent_id: int = 0): - """ + r""" Args: - agent_id: id of agent + agent_id: id of agent. Returns: - state of agent corresponding to agent_id + state of agent corresponding to agent_id. """ raise NotImplementedError @@ -302,26 +294,27 @@ class Simulator: raise NotImplementedError def sample_navigable_point(self) -> List[float]: - """Samples a navigable point from the simulator. A point is defined as + r"""Samples a navigable point from the simulator. A point is defined as navigable if the agent can be initialized at that point. Returns: - Navigable point. + navigable point. """ raise NotImplementedError def is_navigable(self, point: List[float]) -> bool: - """Return true if the agent can stand at the specified point. + r"""Return true if the agent can stand at the specified point. Args: - point: The point to check. + point: the point to check. """ raise NotImplementedError def action_space_shortest_path( self, source: AgentState, targets: List[AgentState], agent_id: int = 0 ) -> List[ShortestPathPoint]: - """Calculates the shortest path between source and target agent states. + r"""Calculates the shortest path between source and target agent + states. Args: source: source agent state for shortest path calculation. @@ -329,7 +322,7 @@ class Simulator: agent_id: id for agent (relevant for multi-agent setup). Returns: - List of agent states and actions along the shortest path from + list of agent states and actions along the shortest path from source to the nearest target (both included). """ raise NotImplementedError @@ -337,31 +330,32 @@ class Simulator: def get_straight_shortest_path_points( self, position_a: List[float], position_b: List[float] ) -> List[List[float]]: - """Returns points along the geodesic (shortest) path between two points - irrespective of the angles between the waypoints. + r"""Returns points along the geodesic (shortest) path between two + points irrespective of the angles between the waypoints. Args: - position_a: The start point. This will be the first point in the + position_a: the start point. This will be the first point in the returned list. - position_b: The end point. This will be the last point in the + position_b: the end point. This will be the last point in the returned list. + Returns: - A list of waypoints (x, y, z) on the geodesic path between the two + a list of waypoints (x, y, z) on the geodesic path between the two points. - """ + """ raise NotImplementedError @property def up_vector(self): - """The vector representing the direction upward (perpendicular to the + r"""The vector representing the direction upward (perpendicular to the floor) from the global coordinate frame. """ raise NotImplementedError @property def forward_vector(self): - """The forward direction in the global coordinate frame i.e. the + r"""The forward direction in the global coordinate frame i.e. the direction of forward movement for an agent with 0 degrees rotation in the ground plane. """ diff --git a/habitat/core/utils.py b/habitat/core/utils.py index 286aab16b38a359bc4c2072562cfd5ec70ee3c6f..b5e338fc31454a3768271a8d88feb3a05663d9d2 100644 --- a/habitat/core/utils.py +++ b/habitat/core/utils.py @@ -10,7 +10,7 @@ import numpy as np def tile_images(images: List[np.ndarray]) -> np.ndarray: - """Tile multiple images into single image + r"""Tile multiple images into single image Args: images: list of images where each image has dimension diff --git a/habitat/core/vector_env.py b/habitat/core/vector_env.py index d5fc6d387587662f60ed81c859cacb4472b9e648..be8c735540f32b17707e8c884d07513c1afe46f7 100644 --- a/habitat/core/vector_env.py +++ b/habitat/core/vector_env.py @@ -32,7 +32,7 @@ CALL_COMMAND = "call" def _make_env_fn( config: Config, dataset: Optional[habitat.Dataset] = None, rank: int = 0 ) -> Env: - """Constructor for default habitat Env. + r"""Constructor for default habitat Env. Args: config: configuration for environment. @@ -40,7 +40,7 @@ def _make_env_fn( rank: rank for setting seed of environment Returns: - Env/RLEnv object + ``Env``/``RLEnv`` object """ habitat_env = Env(config=config, dataset=dataset) habitat_env.seed(config.SEED + rank) @@ -48,18 +48,18 @@ def _make_env_fn( class VectorEnv: - """Vectorized environment which creates multiple processes where each + r"""Vectorized environment which creates multiple processes where each process runs its own environment. All the environments are synchronized on step and reset methods. Args: - make_env_fn: Function which creates a single environment. An + make_env_fn: function which creates a single environment. An environment can be of type Env or RLEnv env_fn_args: tuple of tuple of args to pass to the make_env_fn. auto_reset_done: automatically reset the environment when done. This functionality is provided for seamless training of vectorized environments. - multiprocessing_start_method: The multiprocessing method used to + multiprocessing_start_method: the multiprocessing method used to spawn worker processes. Valid methods are ``{'spawn', 'forkserver', 'fork'}`` ``'forkserver'`` is the recommended method as it works well with CUDA. If @@ -123,9 +123,9 @@ class VectorEnv: @property def num_envs(self): - """ + r""" Returns: - Number of individual environments. + number of individual environments. """ return self._num_envs - len(self._paused) @@ -139,7 +139,7 @@ class VectorEnv: child_pipe: Optional[Connection] = None, parent_pipe: Optional[Connection] = None, ) -> None: - r"""Process worker for creating and interacting with the environment. + r"""process worker for creating and interacting with the environment. """ env = env_fn(*env_fn_args) if parent_pipe is not None: @@ -232,10 +232,10 @@ class VectorEnv: ) def reset(self): - """Reset all the vectorized environments + r"""Reset all the vectorized environments Returns: - List of outputs from the reset method of envs. + list of outputs from the reset method of envs. """ self._is_waiting = True for write_fn in self._connection_write_fns: @@ -247,13 +247,13 @@ class VectorEnv: return results def reset_at(self, index_env: int): - """Reset in the index_env environment in the vector. + r"""Reset in the index_env environment in the vector. Args: index_env: index of the environment to be reset Returns: - List containing the output of reset method of indexed env. + list containing the output of reset method of indexed env. """ self._is_waiting = True self._connection_write_fns[index_env]((RESET_COMMAND, None)) @@ -262,14 +262,14 @@ class VectorEnv: return results def step_at(self, index_env: int, action: int): - """Step in the index_env environment in the vector. + r"""Step in the index_env environment in the vector. Args: index_env: index of the environment to be stepped into action: action to be taken Returns: - List containing the output of step method of indexed env. + list containing the output of step method of indexed env. """ self._is_waiting = True self._connection_write_fns[index_env]((STEP_COMMAND, action)) @@ -278,7 +278,7 @@ class VectorEnv: return results def async_step(self, actions: List[int]) -> None: - """Asynchronously step in the environments. + r"""Asynchronously step in the environments. Args: actions: actions to be performed in the vectorized envs. @@ -288,7 +288,7 @@ class VectorEnv: write_fn((STEP_COMMAND, action)) def wait_step(self) -> List[Observations]: - """Wait until all the asynchronized environments have synchronized. + r"""Wait until all the asynchronized environments have synchronized. """ observations = [] for read_fn in self._connection_read_fns: @@ -297,14 +297,14 @@ class VectorEnv: return observations def step(self, actions: List[int]): - """Perform actions in the vectorized environments. + r"""Perform actions in the vectorized environments. Args: actions: list of size _num_envs containing action to be taken in each environment. Returns: - List of outputs from the step method of envs. + list of outputs from the step method of envs. """ self.async_step(actions) return self.wait_step() @@ -332,10 +332,10 @@ class VectorEnv: self._is_closed = True def pause_at(self, index: int) -> None: - """Pauses computation on this env without destroying the env. This is - useful for not needing to call steps on all environments when only - some are active (for example during the last episodes of running - eval episodes). + r"""Pauses computation on this env without destroying the env. This is + useful for not needing to call steps on all environments when only + some are active (for example during the last episodes of running + eval episodes). Args: index: which env to pause. All indexes after this one will be @@ -350,7 +350,7 @@ class VectorEnv: self._paused.append((index, read_fn, write_fn, worker)) def resume_all(self) -> None: - """Resumes any paused envs. + r"""Resumes any paused envs. """ for index, read_fn, write_fn, worker in reversed(self._paused): self._connection_read_fns.insert(index, read_fn) @@ -364,15 +364,16 @@ class VectorEnv: function_name: str, function_args: Optional[List[Any]] = None, ) -> Any: - """Calls a function (which is passed by name) on the selected env and - returns the result. + r"""Calls a function (which is passed by name) on the selected env and + returns the result. Args: - index: Which env to call the function on. - function_name: The name of the function to call on the env. - function_args: Optional function args. + index: which env to call the function on. + function_name: the name of the function to call on the env. + function_args: optional function args. + Returns: - A The result of calling the function. + result of calling the function. """ self._is_waiting = True self._connection_write_fns[index]( @@ -387,16 +388,17 @@ class VectorEnv: function_names: List[str], function_args_list: Optional[List[Any]] = None, ) -> List[Any]: - """Calls a list of functions (which are passed by name) on the - corresponding env (by index). + r"""Calls a list of functions (which are passed by name) on the + corresponding env (by index). Args: - function_names: The name of the functions to call on the envs. - function_args_list: List of function args for each function. If + function_names: the name of the functions to call on the envs. + function_args_list: list of function args for each function. If provided, len(function_args_list) should be as long as len(function_names). + Returns: - A The result of calling the function. + result of calling the function. """ self._is_waiting = True if function_args_list is None: @@ -416,7 +418,7 @@ class VectorEnv: def render( self, mode: str = "human", *args, **kwargs ) -> Union[np.ndarray, None]: - """Render observations from all environments in a tiled image. + r"""Render observations from all environments in a tiled image. """ for write_fn in self._connection_write_fns: write_fn((RENDER_COMMAND, (args, {"mode": "rgb", **kwargs}))) @@ -448,6 +450,13 @@ class VectorEnv: class ThreadedVectorEnv(VectorEnv): + r"""Provides same functionality as ``VectorEnv``, the only difference is it + runs in a multi-thread setup inside a single process. ``VectorEnv`` runs + in a multi-proc setup. This makes it much easier to debug when using + ``VectorEnv`` because you can actually put break points in the environment + methods. It should not be used for best performance. + """ + def _spawn_workers( self, env_fn_args: Iterable[Tuple[Any, ...]], diff --git a/habitat/datasets/eqa/mp3d_eqa_dataset.py b/habitat/datasets/eqa/mp3d_eqa_dataset.py index ca09fcfcfdf9d73ff779a5b4e758e8ec4e4ef607..efb24c489d5095c33b54ba8c24dbdba4800f64b1 100644 --- a/habitat/datasets/eqa/mp3d_eqa_dataset.py +++ b/habitat/datasets/eqa/mp3d_eqa_dataset.py @@ -29,7 +29,7 @@ def get_default_mp3d_v1_config(split: str = "val"): @registry.register_dataset(name="MP3DEQA-v1") class Matterport3dDatasetV1(Dataset): - """Class inherited from Dataset that loads Matterport3D + r"""Class inherited from Dataset that loads Matterport3D Embodied Question Answering dataset. This class can then be used as follows:: diff --git a/habitat/datasets/pointnav/pointnav_dataset.py b/habitat/datasets/pointnav/pointnav_dataset.py index 97bf78440aad1f948b504eee0765e4f6d8b396e3..6dba0b62471e241fe69a60bf8f1103aef54731ec 100644 --- a/habitat/datasets/pointnav/pointnav_dataset.py +++ b/habitat/datasets/pointnav/pointnav_dataset.py @@ -25,8 +25,7 @@ DEFAULT_SCENE_PATH_PREFIX = "data/scene_datasets/" @registry.register_dataset(name="PointNav-v1") class PointNavDatasetV1(Dataset): - """ - Class inherited from Dataset that loads Point Navigation dataset. + r"""Class inherited from Dataset that loads Point Navigation dataset. """ episodes: List[NavigationEpisode] @@ -40,7 +39,7 @@ class PointNavDatasetV1(Dataset): @staticmethod def get_scenes_to_load(config: Config) -> List[str]: - """Return list of scene ids for which dataset has separate files with + r"""Return list of scene ids for which dataset has separate files with episodes. """ assert PointNavDatasetV1.check_config_paths_exist(config) diff --git a/habitat/datasets/pointnav/pointnav_generator.py b/habitat/datasets/pointnav/pointnav_generator.py index 2fbd79108bc48dedbb8addab0684c607205f955f..8b08174be56e7e277b8456c443a63d828c8190bd 100644 --- a/habitat/datasets/pointnav/pointnav_generator.py +++ b/habitat/datasets/pointnav/pointnav_generator.py @@ -6,17 +6,15 @@ from habitat.core.simulator import Simulator from habitat.datasets.utils import get_action_shortest_path from habitat.tasks.nav.nav_task import NavigationEpisode, NavigationGoal -""" - A minimum radius of a plane that a point should be part of to be - considered as a target or source location. Used to filter isolated points - that aren't part of a floor. +r"""A minimum radius of a plane that a point should be part of to be +considered as a target or source location. Used to filter isolated points +that aren't part of a floor. """ ISLAND_RADIUS_LIMIT = 1.5 def _ratio_sample_rate(ratio: float, ratio_threshold: float) -> float: - """ - Sampling function for aggressive filtering of straight-line + r"""Sampling function for aggressive filtering of straight-line episodes with shortest path geodesic distance to Euclid distance ratio threshold. @@ -85,8 +83,7 @@ def generate_pointnav_episode( geodesic_to_euclid_min_ratio: float = 1.1, number_retries_per_target: int = 10, ) -> NavigationEpisode: - """ - Generator function that generates PointGoal navigation episodes. + r"""Generator function that generates PointGoal navigation episodes. An episode is trivial if there is an obstacle-free, straight line between the start and goal positions. A good measure of the navigation diff --git a/habitat/sims/habitat_simulator.py b/habitat/sims/habitat_simulator.py index d6c0c3a093ebfa5452843890740b2f27197aa0ac..2b98b6d849b35fb5de96808d6fef04e2cc39611f 100644 --- a/habitat/sims/habitat_simulator.py +++ b/habitat/sims/habitat_simulator.py @@ -139,7 +139,7 @@ class HabitatSimSemanticSensor(SemanticSensor): @registry.register_simulator(name="Sim-v0") class HabitatSim(Simulator): - """Simulator wrapper over habitat-sim + r"""Simulator wrapper over habitat-sim habitat-sim repo: https://github.com/facebookresearch/habitat-sim @@ -281,7 +281,7 @@ class HabitatSim(Simulator): return observations def render(self, mode: str = "rgb") -> Any: - """ + r""" Args: mode: sensor whose observation is used for returning the frame, eg: "rgb", "depth", "semantic" @@ -323,7 +323,7 @@ class HabitatSim(Simulator): def action_space_shortest_path( self, source: AgentState, targets: List[AgentState], agent_id: int = 0 ) -> List[ShortestPathPoint]: - """ + r""" Returns: List of agent states and actions along the shortest path from source to the nearest target (both included). If one of the @@ -360,7 +360,7 @@ class HabitatSim(Simulator): return self._sim.pathfinder.is_navigable(point) def semantic_annotations(self): - """ + r""" Returns: SemanticScene which is a three level hierarchy of semantic annotations for the current scene. Specifically this method @@ -422,7 +422,7 @@ class HabitatSim(Simulator): agent_id: int = 0, reset_sensors: bool = True, ) -> bool: - """Sets agent state similar to initialize_agent, but without agents + r"""Sets agent state similar to initialize_agent, but without agents creation. On failure to place the agent in the proper position, it is moved back to its previous pose. diff --git a/habitat/tasks/eqa/eqa_task.py b/habitat/tasks/eqa/eqa_task.py index dbb0c1f0d6321fd154c410307f72529ba6c559a0..6f765696f7005dd466f7e31649294e5f7c4fc8d2 100644 --- a/habitat/tasks/eqa/eqa_task.py +++ b/habitat/tasks/eqa/eqa_task.py @@ -30,7 +30,7 @@ class QuestionData: @attr.s(auto_attribs=True, kw_only=True) class EQAEpisode(NavigationEpisode): - """Specification of episode that includes initial position and rotation of + r"""Specification of episode that includes initial position and rotation of agent, goal, question specifications and optional shortest paths. Args: diff --git a/habitat/tasks/nav/nav_task.py b/habitat/tasks/nav/nav_task.py index 578cccc5b7454bf20f82ca57a1a85edbed4bfbb7..a6bf8df3766c9f8c48e4e15e40acd769ee08cf0e 100644 --- a/habitat/tasks/nav/nav_task.py +++ b/habitat/tasks/nav/nav_task.py @@ -52,7 +52,7 @@ def merge_sim_episode_config( @attr.s(auto_attribs=True, kw_only=True) class NavigationGoal: - """Base class for a goal specification hierarchy. + r"""Base class for a goal specification hierarchy. """ position: List[float] = attr.ib(default=None, validator=not_none_validator) @@ -61,7 +61,7 @@ class NavigationGoal: @attr.s(auto_attribs=True, kw_only=True) class ObjectGoal(NavigationGoal): - """Object goal that can be specified by object_id or position or object + r"""Object goal that can be specified by object_id or position or object category. """ @@ -74,7 +74,7 @@ class ObjectGoal(NavigationGoal): @attr.s(auto_attribs=True, kw_only=True) class RoomGoal(NavigationGoal): - """Room goal that can be specified by room_id or position with radius. + r"""Room goal that can be specified by room_id or position with radius. """ room_id: str = attr.ib(default=None, validator=not_none_validator) @@ -83,7 +83,7 @@ class RoomGoal(NavigationGoal): @attr.s(auto_attribs=True, kw_only=True) class NavigationEpisode(Episode): - """Class for episode specification that includes initial position and + r"""Class for episode specification that includes initial position and rotation of agent, scene name, goal and optional shortest paths. An episode is a description of one task instance for the agent. @@ -108,8 +108,7 @@ class NavigationEpisode(Episode): @registry.register_sensor class PointGoalSensor(Sensor): - """ - Sensor for PointGoal observations which are used in the PointNav task. + r"""Sensor for PointGoal observations which are used in the PointNav task. For the agent in simulator the forward direction is along negative-z. In polar coordinate format the angle returned is azimuth to the goal. @@ -175,8 +174,7 @@ class PointGoalSensor(Sensor): @registry.register_sensor class StaticPointGoalSensor(Sensor): - """ - Sensor for PointGoal observations which are used in the StaticPointNav + r"""Sensor for PointGoal observations which are used in the StaticPointNav task. For the agent in simulator the forward direction is along negative-z. In polar coordinate format the angle returned is azimuth to the goal. Args: @@ -248,8 +246,8 @@ class StaticPointGoalSensor(Sensor): @registry.register_sensor class HeadingSensor(Sensor): - """ - Sensor for observing the agent's heading in the global coordinate frame. + r"""Sensor for observing the agent's heading in the global coordinate + frame. Args: sim: reference to the simulator for calculating task observations. @@ -285,8 +283,7 @@ class HeadingSensor(Sensor): @registry.register_sensor class ProximitySensor(Sensor): - """ - Sensor for observing the distance to the closest obstacle + r"""Sensor for observing the distance to the closest obstacle Args: sim: reference to the simulator for calculating task observations. @@ -324,7 +321,7 @@ class ProximitySensor(Sensor): @registry.register_measure class SPL(Measure): - """SPL (Success weighted by Path Length) + r"""SPL (Success weighted by Path Length) ref: On Evaluation of Embodied Agents - Anderson et. al https://arxiv.org/pdf/1807.06757.pdf @@ -410,7 +407,7 @@ class Collisions(Measure): @registry.register_measure class TopDownMap(Measure): - """Top Down Map measure + r"""Top Down Map measure """ def __init__(self, sim: Simulator, config: Config): diff --git a/habitat/tasks/nav/shortest_path_follower.py b/habitat/tasks/nav/shortest_path_follower.py index 7d6da161ba4a6addc95e19b5627863ae8c29593b..a358cab5b829423f09fa206b7822f81dfbeaabed 100644 --- a/habitat/tasks/nav/shortest_path_follower.py +++ b/habitat/tasks/nav/shortest_path_follower.py @@ -25,7 +25,7 @@ def action_to_one_hot(action: int) -> np.array: class ShortestPathFollower: - """Utility class for extracting the action on the shortest path to the + r"""Utility class for extracting the action on the shortest path to the goal. Args: sim: HabitatSim instance. @@ -69,7 +69,8 @@ class ShortestPathFollower: def get_next_action( self, goal_pos: np.array ) -> Union[SimulatorActions, np.array]: - """Returns the next action along the shortest path.""" + r"""Returns the next action along the shortest path. + """ if ( np.linalg.norm(goal_pos - self._sim.get_agent_state().position) <= self._goal_radius @@ -182,7 +183,7 @@ class ShortestPathFollower: @mode.setter def mode(self, new_mode: str): - """Sets the mode for how the greedy follower determines the best next + r"""Sets the mode for how the greedy follower determines the best next step. Args: new_mode: geodesic_path indicates using the simulator's shortest diff --git a/habitat/tasks/utils.py b/habitat/tasks/utils.py index d41f9b7842f43c1dbf47dce6a8f9cc0c57d4223a..ceb36600d6d6d1874ef8ea6b153ec255b4b9475a 100644 --- a/habitat/tasks/utils.py +++ b/habitat/tasks/utils.py @@ -9,7 +9,7 @@ import quaternion # noqa # pylint: disable=unused-import def quaternion_to_rotation(q_r, q_i, q_j, q_k): - """ + r""" ref: https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation """ s = 1 # unit quaternion diff --git a/habitat/utils/geometry_utils.py b/habitat/utils/geometry_utils.py index ac454f4d94f6b1f6c6abc7ed09cbcee97c59bce4..793387eaa31cabfb332d173ca6b03ad5ee4ab9b5 100644 --- a/habitat/utils/geometry_utils.py +++ b/habitat/utils/geometry_utils.py @@ -11,7 +11,7 @@ EPSILON = 1e-8 def angle_between_quaternions(q1: np.quaternion, q2: np.quaternion) -> float: - """Returns the angle (in radians) between two quaternions. This angle will + r"""Returns the angle (in radians) between two quaternions. This angle will always be positive. """ q1_inv = np.conjugate(q1) @@ -21,7 +21,8 @@ def angle_between_quaternions(q1: np.quaternion, q2: np.quaternion) -> float: def quaternion_from_two_vectors(v0: np.array, v1: np.array) -> np.quaternion: - """Computes the quaternion representation of v1 using v0 as the origin.""" + r"""Computes the quaternion representation of v1 using v0 as the origin. + """ v0 = v0 / np.linalg.norm(v0) v1 = v1 / np.linalg.norm(v1) c = v0.dot(v1) diff --git a/habitat/utils/visualizations/maps.py b/habitat/utils/visualizations/maps.py index fbd7eb6fe20296f8074c94c157966c5a65aa3b60..f8dbb171becd64c83b2542cf822b9b4be8f78195 100644 --- a/habitat/utils/visualizations/maps.py +++ b/habitat/utils/visualizations/maps.py @@ -51,7 +51,7 @@ def draw_agent( agent_rotation: float, agent_radius_px: int = 5, ) -> np.ndarray: - """Return an image with the agent image composited onto it. + r"""Return an image with the agent image composited onto it. Args: image: the image onto which to put the agent. agent_center_coord: the image coordinates where to paste the agent. @@ -91,7 +91,7 @@ def pointnav_draw_target_birdseye_view( target_band_radii: Optional[List[float]] = None, target_band_colors: Optional[List[Tuple[int, int, int]]] = None, ) -> np.ndarray: - """Return an image of agent w.r.t. centered target location for pointnav + r"""Return an image of agent w.r.t. centered target location for pointnav tasks. Args: @@ -183,7 +183,7 @@ def to_grid( coordinate_max: float, grid_resolution: Tuple[int, int], ) -> Tuple[int, int]: - """Return gridworld index of realworld coordinates assuming top-left corner + r"""Return gridworld index of realworld coordinates assuming top-left corner is the origin. The real world coordinates of lower left corner are (coordinate_min, coordinate_min) and of top right corner are (coordinate_max, coordinate_max) @@ -204,7 +204,7 @@ def from_grid( coordinate_max: float, grid_resolution: Tuple[int, int], ) -> Tuple[float, float]: - """Inverse of _to_grid function. Return real world coordinate from + r"""Inverse of _to_grid function. Return real world coordinate from gridworld assuming top-left corner is the origin. The real world coordinates of lower left corner are (coordinate_min, coordinate_min) and of top right corner are (coordinate_max, coordinate_max) @@ -246,7 +246,7 @@ def get_topdown_map( num_samples: int = 20000, draw_border: bool = True, ) -> np.ndarray: - """Return a top-down occupancy map for a sim. Note, this only returns valid + r"""Return a top-down occupancy map for a sim. Note, this only returns valid values for whatever floor the agent is currently on. Args: @@ -327,7 +327,7 @@ def get_topdown_map( def colorize_topdown_map(top_down_map: np.ndarray) -> np.ndarray: - """Convert the top down map to RGB based on the indicator values. + r"""Convert the top down map to RGB based on the indicator values. Args: top_down_map: A non-colored version of the map. Returns: diff --git a/habitat/utils/visualizations/utils.py b/habitat/utils/visualizations/utils.py index 47a21a84c98357f80ae8944aa74da2d85e29ecc8..a051df99fe9caca27829bc5678961d5cb570eeff 100644 --- a/habitat/utils/visualizations/utils.py +++ b/habitat/utils/visualizations/utils.py @@ -18,7 +18,7 @@ def paste_overlapping_image( location: Tuple[int, int], mask: Optional[np.ndarray] = None, ): - """Composites the foreground onto the background dealing with edge + r"""Composites the foreground onto the background dealing with edge boundaries. Args: background: the background image to paste on. @@ -98,7 +98,7 @@ def images_to_video( quality: Optional[float] = 5, **kwargs ): - """Calls imageio to run FFMPEG on a list of images. For more info on + r"""Calls imageio to run FFMPEG on a list of images. For more info on parameters, see https://imageio.readthedocs.io/en/stable/format_ffmpeg.html Args: images: The list of images. Images should be HxWx3 in RGB order. diff --git a/habitat_baselines/config/default.py b/habitat_baselines/config/default.py index ee9c62d7d46bdd5f39a6d202adf55fb4b531e750..c7506e9e19dd08f600a1c171aaa308ac7220b7a9 100644 --- a/habitat_baselines/config/default.py +++ b/habitat_baselines/config/default.py @@ -67,8 +67,7 @@ def get_config( config_paths: Optional[Union[List[str], str]] = None, opts: Optional[list] = None, ) -> CN: - """ - Create a unified config with default values overwritten by values from + r"""Create a unified config with default values overwritten by values from `config_paths` and overwritten by options from `opts`. Args: config_paths: List of config paths or string that contains comma diff --git a/habitat_baselines/rl/ppo/policy.py b/habitat_baselines/rl/ppo/policy.py index 5c9e725633fff4666dbab465e01a66e59b3f504f..8a7182f720079f8933c86439e4630182d03dc97a 100644 --- a/habitat_baselines/rl/ppo/policy.py +++ b/habitat_baselines/rl/ppo/policy.py @@ -59,7 +59,7 @@ class Policy(nn.Module): class Net(nn.Module): - """Network which passes the input image through CNN and concatenates + r"""Network which passes the input image through CNN and concatenates goal vector with CNN's output and passes that through RNN. """ @@ -152,7 +152,7 @@ class Net(nn.Module): def _conv_output_dim( self, dimension, padding, dilation, kernel_size, stride ): - """Calculates the output height and width based on the input + r"""Calculates the output height and width based on the input height and width to the convolution layer. ref: https://pytorch.org/docs/master/nn.html#torch.nn.Conv2d diff --git a/habitat_baselines/rl/ppo/utils.py b/habitat_baselines/rl/ppo/utils.py index e7c7e5c9bd0485344f0446763309fc3c920a5b40..0fed7445359b06b09d3491ba2d99451da92aadf1 100644 --- a/habitat_baselines/rl/ppo/utils.py +++ b/habitat_baselines/rl/ppo/utils.py @@ -53,7 +53,8 @@ def _flatten_helper(t, n, tensor): def update_linear_schedule(optimizer, epoch, total_num_epochs, initial_lr): - """Decreases the learning rate linearly""" + r"""Decreases the learning rate linearly + """ lr = initial_lr - (initial_lr * (epoch / float(total_num_epochs))) for param_group in optimizer.param_groups: param_group["lr"] = lr diff --git a/habitat_baselines/slambased/mappers.py b/habitat_baselines/slambased/mappers.py index 90b16cd3b0fd226b526d0802c7ae3aa31b91e905..1c21a44abb655594e6de47e90ab2af3cf8815c9c 100644 --- a/habitat_baselines/slambased/mappers.py +++ b/habitat_baselines/slambased/mappers.py @@ -10,7 +10,7 @@ from habitat_baselines.slambased.reprojection import ( def depth2local3d(depth, fx, fy, cx, cy): - """Projects depth map to 3d point cloud + r"""Projects depth map to 3d point cloud with origin in the camera focus """ device = depth.device @@ -30,7 +30,7 @@ def depth2local3d(depth, fx, fy, cx, cy): def pcl_to_obstacles(pts3d, map_size=40, cell_size=0.2, min_pts=10): - """Counts number of 3d points in 2d map cell. + r"""Counts number of 3d points in 2d map cell. Height is sum-pooled. """ device = pts3d.device @@ -56,7 +56,7 @@ def pcl_to_obstacles(pts3d, map_size=40, cell_size=0.2, min_pts=10): class DirectDepthMapper(nn.Module): - """Estimates obstacle map given the depth image + r"""Estimates obstacle map given the depth image ToDo: replace numpy histogram counting with differentiable pytorch soft count like in https://papers.nips.cc/paper/7545-unsupervised-learning-of-shape-and-pose-with-differentiable-point-clouds.pdf diff --git a/habitat_baselines/slambased/monodepth.py b/habitat_baselines/slambased/monodepth.py index a1f87b79370af53a2449e9427114c267b1054e21..80e0d7e752d41745c5909af1c49bfd8890725c9d 100644 --- a/habitat_baselines/slambased/monodepth.py +++ b/habitat_baselines/slambased/monodepth.py @@ -1,5 +1,4 @@ -""" -The code below is taked from https://github.com/JunjH/Revisiting_Single_Depth_Estimation +r"""The code below is taked from https://github.com/JunjH/Revisiting_Single_Depth_Estimation Revisiting Single Image Depth Estimation: Toward Higher Resolution Maps With Accurate Object Boundaries Junjie Hu and Mete Ozay and Yan Zhang and Takayuki Okatani WACV 2019 @@ -19,8 +18,7 @@ import torch.utils.model_zoo as model_zoo from PIL import Image from torchvision import transforms, utils -""" -ResNet code gently borrowed from +r"""ResNet code gently borrowed from https://github.com/pytorch/vision/blob/master/torchvision/models/py """ @@ -197,7 +195,7 @@ class ResNet(nn.Module): def resnet18(pretrained=False, **kwargs): - """Constructs a ResNet-18 model. + r"""Constructs a ResNet-18 model. Args: pretrained (bool): If True, returns a model pre-trained on ImageNet """ @@ -208,7 +206,7 @@ def resnet18(pretrained=False, **kwargs): def resnet34(pretrained=False, **kwargs): - """Constructs a ResNet-34 model. + r"""Constructs a ResNet-34 model. Args: pretrained (bool): If True, returns a model pre-trained on ImageNet """ @@ -219,7 +217,7 @@ def resnet34(pretrained=False, **kwargs): def resnet50(pretrained=False, **kwargs): - """Constructs a ResNet-50 model. + r"""Constructs a ResNet-50 model. Args: pretrained (bool): If True, returns a model pre-trained on ImageNet """ @@ -234,7 +232,7 @@ def resnet50(pretrained=False, **kwargs): def resnet101(pretrained=False, **kwargs): - """Constructs a ResNet-101 model. + r"""Constructs a ResNet-101 model. Args: pretrained (bool): If True, returns a model pre-trained on ImageNet """ @@ -245,7 +243,7 @@ def resnet101(pretrained=False, **kwargs): def resnet152(pretrained=False, **kwargs): - """Constructs a ResNet-152 model. + r"""Constructs a ResNet-152 model. Args: pretrained (bool): If True, returns a model pre-trained on ImageNet """ @@ -534,7 +532,7 @@ class CenterCrop(object): class ToTensor(object): - """Convert a ``PIL.Image`` or ``numpy.ndarray`` to tensor. + r"""Convert a ``PIL.Image`` or ``numpy.ndarray`` to tensor. Converts a PIL.Image or numpy.ndarray (H x W x C) in the range [0, 255] to a torch.FloatTensor of shape (C x H x W) in the range [0.0, 1.0]. """ diff --git a/habitat_baselines/slambased/reprojection.py b/habitat_baselines/slambased/reprojection.py index 7d79f6d7410788bb77e1fa6b730e81079ae88da1..a1feff84b9b783cdc7b739e39a61848960acefde 100644 --- a/habitat_baselines/slambased/reprojection.py +++ b/habitat_baselines/slambased/reprojection.py @@ -141,7 +141,7 @@ def add_rot_wps(p): def planned_path2tps(path, cell_size, map_size, agent_h, add_rot=False): - """Path is list of 2d coordinates from planner, in map cells. + r"""Path is list of 2d coordinates from planner, in map cells. tp is trajectory pose, 4x4 matrix - same format, as in localization module """ @@ -172,7 +172,7 @@ def planned_path2tps(path, cell_size, map_size, agent_h, add_rot=False): def habitat_goalpos_to_tp(ro_phi, p_curr): - """Convert distance and azimuth to + r"""Convert distance and azimuth to trajectory pose, 4x4 matrix - same format, as in localization module """ @@ -202,7 +202,7 @@ def habitat_goalpos_to_tp(ro_phi, p_curr): def habitat_goalpos_to_mapgoal_pos(offset, p_curr, cell_size, map_size): - """Convert distance and azimuth to + r"""Convert distance and azimuth to map cell coordinates """ device = offset.device @@ -231,7 +231,7 @@ def homogenize_p(tps): def project_tps_into_worldmap(tps, cell_size, map_size, do_floor=True): - """Convert 4x4 pose matrices (trajectory poses) to + r"""Convert 4x4 pose matrices (trajectory poses) to map cell coordinates """ if len(tps) == 0: diff --git a/docs/img/habitat-api_structure.png b/res/img/habitat-api_structure.png similarity index 100% rename from docs/img/habitat-api_structure.png rename to res/img/habitat-api_structure.png diff --git a/docs/img/habitat_compressed.gif b/res/img/habitat_compressed.gif similarity index 100% rename from docs/img/habitat_compressed.gif rename to res/img/habitat_compressed.gif diff --git a/docs/img/habitat_logo_with_text_horizontal_blue.png b/res/img/habitat_logo_with_text_horizontal_blue.png similarity index 100% rename from docs/img/habitat_logo_with_text_horizontal_blue.png rename to res/img/habitat_logo_with_text_horizontal_blue.png diff --git a/setup.py b/setup.py index a95bae9b43e933e440f6d76edc993ec0aa7ba9bb..655e0cb5b0d511450f04efa37eb9005ce286ac8b 100644 --- a/setup.py +++ b/setup.py @@ -42,8 +42,7 @@ for file_name in glob.glob("**/requirements.txt", recursive=True): class OptionedCommand: - """ - Generic Command class that takes extra user options and modifies + r"""Generic Command class that takes extra user options and modifies arguments in setuptools.setup() accordingly. Though OptionedCommand inherits directly from object, it assumes inheritance from DefaultDevelopCommand or DefaultInstallCommand, as it diff --git a/test/test_habitat_env.py b/test/test_habitat_env.py index e96a34c8e74151f3463422dc3df7049bf8058cbe..7e8b08e77808909de07c2969d72d614bec7b41cb 100644 --- a/test/test_habitat_env.py +++ b/test/test_habitat_env.py @@ -192,7 +192,7 @@ def test_env(): def make_rl_env(config, dataset, rank: int = 0): - """Constructor for default habitat Env. + r"""Constructor for default habitat Env. :param config: configurations for environment :param dataset: dataset for environment :param rank: rank for setting seeds for environment diff --git a/test/test_install.py b/test/test_install.py index f851bf1cc21862d0ee19a1701af7a3d8f1aaa25c..bc5969f69bcc9bd263b02d91304503d30f9e06a2 100644 --- a/test/test_install.py +++ b/test/test_install.py @@ -9,5 +9,6 @@ from habitat.core.logging import logger def test_habitat_install(): - """dummy test for testing installation""" + r"""dummy test for testing installation + """ logger.info(str(habitat))