Configuration
A MetaDrive instance accepts a dict as the environmental config. For example, you can build a MetaDrive instance with 200 generated maps via
from metadrive import MetaDriveEnv
config = dict(num_scenarios=200, start_seed=0)
env = MetaDriveEnv(config)
In this page, we describe the details of the config system and configurable options for all environments.
Config system
This section discusses how to configure the an environment in MetaDrive and some features of the config system.
Overwriting
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. This default config dict can be accessed via the class method:
default_config = MetaDriveEnv.default_config()
When creating environments, the external config config
will overwritten default values of certain fields in the default_config
. The following code exemplifies this.
from metadrive import MetaDriveEnv
default_config = MetaDriveEnv.default_config()
env = MetaDriveEnv(dict(num_scenarios=100, log_level=50))
env_config = env.config
print("default_config['num_scenarios']:", default_config["num_scenarios"])
print("env_config['num_scenarios']:", env_config["num_scenarios"])
default_config['num_scenarios']: 1
env_config['num_scenarios']: 100
Sanity Check
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.
try:
env = MetaDriveEnv(dict(non_exist_key=False))
except KeyError as error:
print(str(error)[:62] + " ...")
"'{'non_exist_key'}' does not exist in existing config. Please ...
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.
try:
env = MetaDriveEnv(dict(num_scenarios=[0, 1]))
except AssertionError as error:
print(str(error)[:62] + " ...")
TypeError: num_scenarios:[0, 1] ...
Basic Config Sharing
The default configs are different across all environments, but may share some identical fields. Take the MetaDriveEnv
and ScenarioEnv
as example.
from metadrive.envs import MetaDriveEnv, ScenarioEnv
metadrive_config = set(MetaDriveEnv.default_config().keys())
scenario_config = set(ScenarioEnv.default_config().keys())
print("Number of parameters of MetaDriveEnv: {}".format(len(metadrive_config)))
print("Number of parameters of ScenarioEnv: {}\n".format(len(scenario_config)))
try:
assert metadrive_config == scenario_config
except AssertionError as error:
print("The config between MetaDriveEnv and ScenarioEnv is different.\n")
identical_parameters = scenario_config.intersection(metadrive_config)
print("Number of identical parameters: \
{}".format(len(identical_parameters)))
print("Number of unique parameters in MetaDriveEnv: \
{}".format(len(metadrive_config-identical_parameters)))
print("Number of unique parameters in ScenarioEnv: \
{}".format(len(scenario_config-identical_parameters)))
Number of parameters of MetaDriveEnv: 114
Number of parameters of ScenarioEnv: 125
The config between MetaDriveEnv and ScenarioEnv is different.
Number of identical parameters: 93
Number of unique parameters in MetaDriveEnv: 21
Number of unique parameters in ScenarioEnv: 32
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.
from metadrive.utils import print_source
print_source(ScenarioEnv.default_config)
@classmethod
def default_config(cls):
config = super(ScenarioEnv, cls).default_config()
config.update(SCENARIO_ENV_CONFIG)
return config
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.
from metadrive.envs.base_env import BaseEnv
set(BaseEnv.default_config()).issubset(set(ScenarioEnv.default_config()))
True
It is the same for the MetaDriveEnv as well, whose default config is:
print_source(MetaDriveEnv.default_config)
@classmethod
def default_config(cls) -> Config:
config = super(MetaDriveEnv, cls).default_config()
config.update(METADRIVE_DEFAULT_CONFIG)
config.register_type("map", str, int)
config["map_config"].register_type("config", None)
return config
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
.
from metadrive.envs.scenario_env import SCENARIO_ENV_CONFIG
assert BaseEnv.default_config()["show_sidewalk"]
assert not ScenarioEnv.default_config()["show_sidewalk"]
assert not SCENARIO_ENV_CONFIG["show_sidewalk"]
Programming with Configs
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. A tutorial of accessing configs when programming new environments is available at config.
Basic Configs
As all environments are subclass of BaseEnv
and share the parameters of BaseEnv
, we first discuss the parameters in BaseEnv.default_config()
.
The available items with annotations are listed as follows.
You can check this in the source code as well.
import metadrive.envs.base_env as base_env
from metadrive.utils import print_source, CONFIG
module_source = print_source(base_env, ["BASE_DEFAULT_CONFIG", ")\n\n"], colorscheme=CONFIG)
BASE_DEFAULT_CONFIG = dict(
# ===== agent =====
# Whether randomize the car model for the agent, randomly choosing from 4 types of cars
random_agent_model=False,
# The ego config is: env_config["vehicle_config"].update(env_config"[agent_configs"]["default_agent"])
agent_configs={DEFAULT_AGENT: dict(use_special_color=True, spawn_lane_index=None)},
# ===== multi-agent =====
# This should be >1 in MARL envs, or set to -1 for spawning as many vehicles as possible.
num_agents=1,
# Turn on this to notify the simulator that it is MARL env
is_multi_agent=False,
# The number of agent will be fixed adn determined at the start of the episode, if set to False
allow_respawn=False,
# How many substeps for the agent to stay static at the death place after done. (Default for MARL: 25)
delay_done=0,
# ===== Action/Control =====
# Please see Documentation: Action and Policy for more details
# What policy to use for controlling agents
agent_policy=EnvInputPolicy,
# If set to True, agent_policy will be overriden and change to ManualControlPolicy
manual_control=False,
# What interfaces to use for manual control, options: "steering_wheel" or "keyboard" or "xbos"
controller="keyboard",
# Used with EnvInputPolicy. If set to True, the env.action_space will be discrete
discrete_action=False,
# If True, use MultiDiscrete action space. Otherwise, use Discrete.
use_multi_discrete=False,
# How many discrete actions are used for steering dim
discrete_steering_dim=5,
# How many discrete actions are used for throttle/brake dim
discrete_throttle_dim=5,
# Check if the action is contained in gym.space. Usually turned off to speed up simulation
action_check=False,
# ===== Observation =====
# Please see Documentation: Observation for more details
# Whether to normalize the pixel value from 0-255 to 0-1
norm_pixel=True,
# The number of timesteps for stacking image observation
stack_size=3,
# Whether to use image observation or lidar. It takes effect in get_single_observation
image_observation=False,
# Like agent_policy, users can use customized observation class through this field
agent_observation=None,
# ===== Termination =====
# The maximum length of each agent episode. Set to None to remove this constraint
horizon=None,
# If set to True, the terminated will be True as well when the length of agent episode exceeds horizon
truncate_as_terminate=False,
# ===== Main Camera =====
# A True value makes the camera follow the reference line instead of the vehicle, making its movement smooth
use_chase_camera_follow_lane=False,
# Height of the main camera
camera_height=2.2,
# Distance between the camera and the vehicle. It is the distance projecting to the x-y plane.
camera_dist=7.5,
# Pitch of main camera. If None, this will be automatically calculated
camera_pitch=None, # degree
# Smooth the camera movement
camera_smooth=True,
# How many frames used to smooth the camera
camera_smooth_buffer_size=20,
# FOV of main camera
camera_fov=65,
# Only available in MARL setting, choosing which agent to track. Values should be "agent0", "agent1" or so on
prefer_track_agent=None,
# Setting the camera position for the Top-down Camera for 3D viewer (pressing key "B" to activate it)
top_down_camera_initial_x=0,
top_down_camera_initial_y=0,
top_down_camera_initial_z=200,
# ===== Vehicle =====
vehicle_config=dict(
# Vehicle model. Candidates: "s", "m", "l", "xl", "default". random_agent_model makes this config invalid
vehicle_model="default",
# If set to True, the vehicle can go backwards with throttle/brake < -1
enable_reverse=False,
# Whether to show the box as navigation points
show_navi_mark=True,
# Whether to show a box mark at the destination
show_dest_mark=False,
# Whether to draw a line from current vehicle position to the designation point
show_line_to_dest=False,
# Whether to draw a line from current vehicle position to the next navigation point
show_line_to_navi_mark=False,
# Whether to draw left / right arrow in the interface to denote the navigation direction
show_navigation_arrow=True,
# If set to True, the vehicle will be in color green in top-down renderer or MARL setting
use_special_color=False,
# Clear wheel friction, so it can not move by setting steering and throttle/brake. Used for ReplayPolicy
no_wheel_friction=False,
# ===== image capturing =====
# Which camera to use for image observation. It should be a sensor registered in sensor config.
image_source="rgb_camera",
# ===== vehicle spawn and navigation =====
# A BaseNavigation instance. It should match the road network type.
navigation_module=None,
# A lane id specifies which lane to spawn this vehicle
spawn_lane_index=None,
# destination lane id. Required only when navigation module is not None.
destination=None,
# the longitudinal and lateral position on the spawn lane
spawn_longitude=5.0,
spawn_lateral=0.0,
# If the following items is assigned, the vehicle will be spawn at the specified position with certain speed
spawn_position_heading=None,
spawn_velocity=None, # m/s
spawn_velocity_car_frame=False,
# ==== others ====
# How many cars the vehicle has overtaken. It is deprecated due to bug.
overtake_stat=False,
# If set to True, the default texture for the vehicle will be replaced with a pure color one.
random_color=False,
# The shape of vehicle are predefined by its class. But in special scenario (WaymoVehicle) we might want to
# set to arbitrary shape.
width=None,
length=None,
height=None,
mass=None,
scale=None, # triplet (x, y, z)
Environment Configs
Please see Environments for unique configs for each environment or check the source code of each environment.