{ "cells": [ { "cell_type": "markdown", "id": "1bc67b98", "metadata": {}, "source": [ "# Configuration\n", "\n", "[![Click and Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/metadriverse/metadrive/blob/main/documentation/source/config_system.ipynb)\n", "\n", "\n", "A MetaDrive instance accepts a dict as the environmental config. For example, you can build a MetaDrive instance with 200 generated maps via \n", "```python\n", "from metadrive import MetaDriveEnv\n", "config = dict(num_scenarios=200, start_seed=0)\n", "env = MetaDriveEnv(config)\n", "```\n", "\n", "In this page, we describe the details of the config system and configurable options for all environments." ] }, { "cell_type": "markdown", "id": "9f006d2e", "metadata": {}, "source": [ "## Config system\n", "This section discusses how to configure the an environment in MetaDrive and some features of the config system.\n", "\n", "### Overwriting\n", "Every environment has a default config, which records the parameters required to launch the environment. It is content is actually a nested dictionary whose keys and values represent the parameter names and corresponding values. \n", "This default config dict can be accessed via the class method:\n", "```python\n", "default_config = MetaDriveEnv.default_config()\n", "```\n", "\n", "When creating environments, the external config `config` will overwritten default values of certain fields in the `default_config`. The following code exemplifies this. " ] }, { "cell_type": "code", "execution_count": null, "id": "355c4e18", "metadata": {}, "outputs": [], "source": [ "from metadrive import MetaDriveEnv\n", "default_config = MetaDriveEnv.default_config()\n", "env = MetaDriveEnv(dict(num_scenarios=100, log_level=50))\n", "env_config = env.config\n", "print(\"default_config['num_scenarios']:\", default_config[\"num_scenarios\"])\n", "print(\"env_config['num_scenarios']:\", env_config[\"num_scenarios\"])" ] }, { "cell_type": "markdown", "id": "e87826b1", "metadata": {}, "source": [ "### Sanity Check\n", "There is a check mechanism which prohibit users to set the value for a key that doesn't exist in the `default_config`. This is helpful to make sure that users type the correct parameter name and successfully config the target parameter. " ] }, { "cell_type": "code", "execution_count": null, "id": "0f825c89", "metadata": {}, "outputs": [], "source": [ "try:\n", " env = MetaDriveEnv(dict(non_exist_key=False))\n", "except KeyError as error:\n", " print(str(error)[:62] + \" ...\")" ] }, { "cell_type": "markdown", "id": "e9d82697", "metadata": {}, "source": [ "The check mechanism will further ensure if the type of the parameter is correct. For example, the `num_scenarios` should be an `int` type, and thus a `list` type parameter will raise an error. " ] }, { "cell_type": "code", "execution_count": null, "id": "e5a35eb4", "metadata": {}, "outputs": [], "source": [ "try:\n", " env = MetaDriveEnv(dict(num_scenarios=[0, 1]))\n", "except AssertionError as error:\n", " print(str(error)[:62] + \" ...\")" ] }, { "cell_type": "markdown", "id": "ebf36961", "metadata": {}, "source": [ "### Basic Config Sharing\n", "The default configs are different across all environments, but may share some identical fields. Take the `MetaDriveEnv` and `ScenarioEnv` as example." ] }, { "cell_type": "code", "execution_count": null, "id": "74d81755", "metadata": {}, "outputs": [], "source": [ "from metadrive.envs import MetaDriveEnv, ScenarioEnv\n", "metadrive_config = set(MetaDriveEnv.default_config().keys())\n", "scenario_config = set(ScenarioEnv.default_config().keys())\n", "print(\"Number of parameters of MetaDriveEnv: {}\".format(len(metadrive_config)))\n", "print(\"Number of parameters of ScenarioEnv: {}\\n\".format(len(scenario_config)))\n", "\n", "try:\n", " assert metadrive_config == scenario_config\n", "except AssertionError as error:\n", " print(\"The config between MetaDriveEnv and ScenarioEnv is different.\\n\")\n", " \n", "identical_parameters = scenario_config.intersection(metadrive_config)\n", "print(\"Number of identical parameters: \\\n", " {}\".format(len(identical_parameters)))\n", "print(\"Number of unique parameters in MetaDriveEnv: \\\n", " {}\".format(len(metadrive_config-identical_parameters)))\n", "print(\"Number of unique parameters in ScenarioEnv: \\\n", " {}\".format(len(scenario_config-identical_parameters)))" ] }, { "cell_type": "markdown", "id": "856d2938", "metadata": {}, "source": [ "It is worth mentioning the parameter sharing mechanism, which is helpful when we create a new environment, so we don't need to copy some common configs to the `default_config` to the new environments again and again. Let's first check out how the `default_config()` function is implemented." ] }, { "cell_type": "code", "execution_count": null, "id": "890a6f47", "metadata": {}, "outputs": [], "source": [ "from metadrive.utils.doc_utils import print_source\n", "print_source(ScenarioEnv.default_config)" ] }, { "cell_type": "markdown", "id": "02bbb322", "metadata": {}, "source": [ "It is quite simple and is implemented by overwriting the `super(ScenarioEnv, cls).default_config()` with `Scenario_ENV_CONFIG`. If we check the contents of the two config dict, we will find that the `BaseEnv.default_config() = super(ScenarioEnv, cls).default_config()` is the subset of `ScenarioEnv.default_config()` and provides the `ScenarioEnv` with the basic configs." ] }, { "cell_type": "code", "execution_count": null, "id": "0bf08048", "metadata": {}, "outputs": [], "source": [ "from metadrive.envs.base_env import BaseEnv\n", "set(BaseEnv.default_config()).issubset(set(ScenarioEnv.default_config()))" ] }, { "cell_type": "markdown", "id": "ee5790d8", "metadata": {}, "source": [ "It is the same for the MetaDriveEnv as well, whose default config is:" ] }, { "cell_type": "code", "execution_count": null, "id": "162c423a", "metadata": {}, "outputs": [], "source": [ "print_source(MetaDriveEnv.default_config)" ] }, { "cell_type": "markdown", "id": "d26cedbd", "metadata": {}, "source": [ "As there is an overwriting function is called, it is ok to overwrite the values of parameters in `BaseEnv.default_config()` when making the `default_config` for a inherited environment. The following code shows that the config `show_sidewalk` is *True* in `BaseEnv` but is overwritten to *False* in `ScenarioEnv` because of the `SCENARIO_ENV_CONFIG`." ] }, { "cell_type": "code", "execution_count": null, "id": "5ccafe53", "metadata": {}, "outputs": [], "source": [ "from metadrive.envs.scenario_env import SCENARIO_ENV_CONFIG\n", "\n", "assert BaseEnv.default_config()[\"show_sidewalk\"]\n", "assert not ScenarioEnv.default_config()[\"show_sidewalk\"]\n", "assert not SCENARIO_ENV_CONFIG[\"show_sidewalk\"]" ] }, { "cell_type": "markdown", "id": "5dab9545-cc22-4634-addf-6553e78abd06", "metadata": {}, "source": [ "### Programming with Configs\n", "\n", "The configs can be accessed everywhere in the program just like the simulation engine instance, so we can use these parameters to adjust the behavior of the simulation.\n", "A tutorial of accessing configs when programming new environments is available at config." ] }, { "cell_type": "markdown", "id": "e43d0c22", "metadata": {}, "source": [ "## Basic Configs\n", "\n", "As all environments are subclass of `BaseEnv` and share the parameters of `BaseEnv`, we first discuss the parameters in `BaseEnv.default_config()`. \n", "The available items with annotations are listed as follows.\n", "You can check this in the source code as well." ] }, { "cell_type": "code", "execution_count": null, "id": "c5100f12", "metadata": {}, "outputs": [], "source": [ "import metadrive.envs.base_env as base_env\n", "from metadrive.utils.doc_utils import print_source, CONFIG\n", "module_source = print_source(base_env, [\"BASE_DEFAULT_CONFIG\", \")\\n\\n\"], colorscheme=CONFIG)" ] }, { "cell_type": "markdown", "id": "62f34482", "metadata": {}, "source": [ "## Environment Configs\n", "Please see [Environments](rl_environments.ipynb) for unique configs for each environment or check the source code of each environment. " ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.17" }, "mystnb": { "execution_mode": "force" } }, "nbformat": 4, "nbformat_minor": 5 }