Random Road¶
Agent has low-level controls of a car and needs to navigate a procedurally generated road network to a goal (parking spot).
The rules are minimal:
Get to your destination in as little time as possible
Don’t crash
Usage¶
env = gym.make("random-road-v0")
env.reset()
Custom generation parameters are passed via config. A deterministic seed can also be specified with env.reset:
generation_params = {
"target_num_endpoints": 50,
"forward_speed": 10,
"age_of_maturity": 4,
"lane_width": 15,
"perlin_variation_params": {
"jitteriness": {"upper": 0.1, "lower": 0.0},
"max_turn_speed": {"upper": 4.0, "lower": 0.01},
"replication_chance": {"upper": 0.7, "lower": 0.0},
"spontaneous_death_chance": {"upper": 0.0, "lower": 0.0},
},
"disable_prints": False,
}
env = gym.make("random-road-v0")
config = {"generation_params": generation_params}
env.reset(seed = 0, options = {'config': config})
Note
It is recommended to pass the generation parameters via options['config'] on calling reset and not at initialization. This is because, during initialization, env.reset is internally called and generates a road network (before being undone by the first external env.reset call). If you decide to provide your own generation parameters under config in gym.make, the vestigal generation call will take an unnecessarily longer amount of time compared to the automatically provided default parameters, which has a target_num_endpoints of only 5 and should finish instantly without significant overhead.
Additionally, pre-existing lanes may be saved for reuse to prevent the unnecessary overhead of generating the same road network from scratch every round.
To do this, use config['preloaded_lanes'] This will overrule your choice of seed and generation parameters.
from highway_env.road.generation.generator import {
save_lanes_to_disk,
load_lanes_from_disk,
}
env = gym.make("random-road-v0")
env.reset()
save_lanes_to_disk("lanes.npz", env.unwrapped.lanes)
[...]
preloaded_lanes = load_lanes_from_disk("lanes.npz")
config = {"preloaded_lanes": preloaded_lanes}
env.reset(options = {'config': config})
Versions¶
ID |
Description |
|---|---|
|
Initial version. Single-agent only. |
Default configuration¶
{
"observation": {
"type": "DictObservation",
"observation_configs": {
"lane_lidar": {"type": "LaneLidarObservation"},
"navigation": {"type": "NavigationObservation"},
"relative_goal": {"type": "RelativeGoalObservation"},
"lidar": {"type": "LidarObservation"},
},
},
"action": {"type": "ContinuousAction"},
"screen_width": 1200,
"screen_height": 700,
"max_timesteps": 1000,
"curb_collision_reward": -10,
"car_collision_reward": -20,
"parking_reward": 10,
"parking_score_threshold": 0.7,
"parking_score_weights": [0.5, 1, 3],
"route_following_reward_scalar": 0.1,
"timestep_reward": -0.01,
"parking_seed": 0,
"generation_params": None,
"preloaded_lanes": None,
"lane_partition_gridsize": 30,
}
More specifically, it is defined in:
- classmethod RandomRoadEnv.default_config() dict[source]
max_timesteps: number of policy timesteps before truncation
curb_collision_reward: one-time penalty after hitting lane border
car_collision_reward: one-time penalty after hitting another vehicle or object
parking_reward: one-time reward after parking in the goal parking spot
parking_score_threshold: determines the threshold of proximity to be parked
parking_score_weights: specifies how much position, velocity, and alignment matter
route_following_reward_scalar: determines the reward/penalty gained by traveling towards/away from the next waypoint
timestep_reward: step/living penalty
parking_seed: pseudorandom seed for determining the placement of parking spots within a generated road network
generation_params: custom parameters to be passed for generation
preloaded_lanes: prevents generation of a new road network by providing an already existing one
lane_partition_gridsize: the size of the grids when partitioning lanes for proximal checks. A lower value can reduce the number of unnecessary checks in dense networks.
Rewards¶
Curb collision penalty
Vehicle-Vehicle collision penalty
Parking reward
Timestep punishment (incentivizes speed)
Route-following reward (scalar projection of velocity onto navigation arrow)
Termination & Truncation¶
Termination occurs when an agent either crashes or parks successfully. Truncation will occur after a fixed number of timesteps.
API¶
- class highway_env.envs.random_road_env.RandomRoadEnv(config: dict | None = None, render_mode: str | None = None)[source]¶
A navigation, negotiation, and parking environment set on a procedurally generated road network.
The goal of an agent is to get to a parking spot as soon as possible without crashing into a curb or other vehicle.
- classmethod default_config() dict[source]¶
max_timesteps: number of policy timesteps before truncation
curb_collision_reward: one-time penalty after hitting lane border
car_collision_reward: one-time penalty after hitting another vehicle or object
parking_reward: one-time reward after parking in the goal parking spot
parking_score_threshold: determines the threshold of proximity to be parked
parking_score_weights: specifies how much position, velocity, and alignment matter
route_following_reward_scalar: determines the reward/penalty gained by traveling towards/away from the next waypoint
timestep_reward: step/living penalty
parking_seed: pseudorandom seed for determining the placement of parking spots within a generated road network
generation_params: custom parameters to be passed for generation
preloaded_lanes: prevents generation of a new road network by providing an already existing one
lane_partition_gridsize: the size of the grids when partitioning lanes for proximal checks. A lower value can reduce the number of unnecessary checks in dense networks.
- create_parking_spots(num_spots: int, spot_width: float, spot_height: float, rng: Generator) bool[source]¶
- Parameters:
num_spots – number of parking spots to generate
spot_width – width of parking spot [must be less than the lane_width]
spot_height – length of parking spot [must be less than forward_speed]
rng – random number generator
- Returns:
whether or not there was enough space to generate the specified number of spots