diff --git a/docs/gettingstarted.rst b/docs/gettingstarted.rst index d117e427a77d16a93929202c2d4fdd61432f1585..c9eb574f51815481845fda55fadcb1d6ae101b7b 100644 --- a/docs/gettingstarted.rst +++ b/docs/gettingstarted.rst @@ -120,5 +120,73 @@ Part 2 : Training a Simple DQN Agent Part 3 : Customizing Observations and Level Generators -------------- +Example code for generating custom observations given a RailEnv and to generate +random rail maps are available in examples/custom_observation_example.py and +examples/custom_railmap_example.py . +Custom observations can be produced by deriving a new object from the +core.env_observation_builder.ObservationBuilder base class, for example as follows: +.. code-block:: python + + class CustomObs(ObservationBuilder): + def __init__(self): + self.observation_space = [5] + + def reset(self): + return + + def get(self, handle): + observation = handle*np.ones((5,)) + return observation + +It is important that an observation_space is defined with a list of dimensions +of the returned observation tensors. get() returns the observation for each agent, +of handle 'handle'. + +A RailEnv environment can then be created as usual: + +.. code-block: python + + env = RailEnv(width=7, + height=7, + rail_generator=random_rail_generator(), + number_of_agents=3, + obs_builder_object=CustomObs()) + +As for generating custom rail maps, the RailEnv class accepts a rail_generator +argument that must be a function with arguments 'width', 'height', 'num_agents', +and 'num_resets=0', and that has to return a GridTransitionMap object (the rail map), +and three lists of tuples containing the (row,column) coordinates of each of +num_agent agents, their initial orientation (0=North, 1=East, 2=South, 3=West), +and the position of their targets. + +For example, the following custom rail map generator returns an empty map of +size (height, width), with no agents (regardless of num_agents): + +.. code-block: python + + def custom_rail_generator(): + def generator(width, height, num_agents=0, num_resets=0): + rail_trans = RailEnvTransitions() + grid_map = GridTransitionMap(width=width, height=height, transitions=rail_trans) + rail_array = grid_map.grid + rail_array.fill(0) + + agents_positions = [] + agents_direction = [] + agents_target = [] + + return grid_map, agents_positions, agents_direction, agents_target + return generator + +It is worth to note that helpful utilities to manage RailEnv environments and their +related data structures are available in 'envs.env_utils'. In particular, +envs.env_utils.get_rnd_agents_pos_tgt_dir_on_rail is fairly handy to fill in +random (but consistent) agents along with their targets and initial directions, +given a rail map (GridTransitionMap object) and the desired number of agents: + +.. code-block: python + agents_position, agents_direction, agents_target = get_rnd_agents_pos_tgt_dir_on_rail( + rail_map, + num_agents)