Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • flatland/flatland
  • stefan_otte/flatland
  • jiaodaxiaozi/flatland
  • sfwatergit/flatland
  • utozx126/flatland
  • ChenKuanSun/flatland
  • ashivani/flatland
  • minhhoa/flatland
  • pranjal_dhole/flatland
  • darthgera123/flatland
  • rivesunder/flatland
  • thomaslecat/flatland
  • joel_joseph/flatland
  • kchour/flatland
  • alex_zharichenko/flatland
  • yoogottamk/flatland
  • troye_fang/flatland
  • elrichgro/flatland
  • jun_jin/flatland
  • nimishsantosh107/flatland
20 results
Show changes
Showing
with 288 additions and 111 deletions
"""Run benchmarks on complex rail flatland."""
import random
import numpy as np
from benchmarker import Benchmarker
from flatland.envs.generators import complex_rail_generator
from flatland.envs.rail_env import RailEnv
def run_benchmark():
"""Run benchmark on a small number of agents in complex rail environment."""
random.seed(1)
np.random.seed(1)
# Example generate a random rail
env = RailEnv(width=15, height=15,
rail_generator=complex_rail_generator(nr_start_goal=5, nr_extra=20, min_dist=12),
number_of_agents=5)
n_trials = 20
action_dict = dict()
action_prob = [0] * 4
def max_lt(seq, val):
"""
Return greatest item in seq for which item < val applies.
None is returned if seq was empty or all items in seq were >= val.
"""
idx = len(seq) - 1
while idx >= 0:
if seq[idx] < val and seq[idx] >= 0:
return seq[idx]
idx -= 1
return None
for trials in range(1, n_trials + 1):
# Reset environment
obs = env.reset()
for a in range(env.get_num_agents()):
norm = max(1, max_lt(obs[a], np.inf))
obs[a] = np.clip(np.array(obs[a]) / norm, -1, 1)
# Run episode
for step in range(100):
# Action
for a in range(env.get_num_agents()):
action = np.random.randint(0, 4)
action_prob[action] += 1
action_dict.update({a: action})
# Environment step
next_obs, all_rewards, done, _ = env.step(action_dict)
for a in range(env.get_num_agents()):
norm = max(1, max_lt(next_obs[a], np.inf))
next_obs[a] = np.clip(np.array(next_obs[a]) / norm, -1, 1)
if done['__all__']:
break
if trials % 100 == 0:
action_prob = [1] * 4
if __name__ == "__main__":
with Benchmarker(cycle=20, extra=1) as bench:
@bench("Everything")
def _(bm):
run_benchmark()
import cProfile
import runpy
import sys
from io import StringIO
import importlib_resources
import pkg_resources
from importlib_resources import path
from benchmarks.benchmark_utils import swap_attr
def profile(resource, entry):
with path(resource, entry) as file_in:
# TODO remove input() from examples
print("*****************************************************************")
print("Profiling {}".format(entry))
print("*****************************************************************")
with swap_attr(sys, "stdin", StringIO("q")):
global my_func
def my_func(): runpy.run_path(file_in, run_name="__main__", init_globals={
'argv': ['--sleep-for-animation=False', '--do_rendering=False']
})
cProfile.run('my_func()', sort='time')
for entry in [entry for entry in importlib_resources.contents('examples') if
not pkg_resources.resource_isdir('examples', entry)
and entry.endswith(".py")
and '__init__' not in entry
and 'demo.py' not in entry
and 'DELETE' not in entry
]:
profile('examples', entry)
import runpy
import sys
from io import StringIO
import importlib_resources
import pkg_resources
from importlib_resources import path
from benchmarks.benchmark_utils import swap_attr
print("run_all_examples.py")
error_log_examples = {}
for entry in [entry for entry in importlib_resources.contents('examples') if
not pkg_resources.resource_isdir('examples', entry)
and entry.endswith(".py")
and '__init__' not in entry
and 'demo.py' not in entry
and 'DELETE' not in entry
]:
with path('examples', entry) as file_in:
print("")
print("")
print("")
print("*****************************************************************")
print("Running {}".format(entry))
print("*****************************************************************")
with swap_attr(sys, "stdin", StringIO("q")):
try:
runpy.run_path(file_in, run_name="__main__", init_globals={
'argv': ['--sleep-for-animation=False', '--do_rendering=False']
})
except Exception as e:
print(e)
error_log_examples.update({file_in: e})
print("runpy done.")
print("Done with {}".format(entry))
if len(error_log_examples.keys()) > 0:
print("*****************************************************************")
print("Error log:")
print("*****************************************************************")
print(error_log_examples)
print("*****************************************************************")
else:
print("*****************************************************************")
print("All examples executed - no error.")
print("*****************************************************************")
Changelog
==========
Changes since Flatland 2.1.0
--------------------------
### Changes in 'schedule_generators'
- Schedule generators now provide the max number of steps allowed per episode
- Pickle files generated with older versions of Flatland need to be regenerated in order to include `_max_episode_steps`
Changes since Flatland 2.0.0
--------------------------
### Changes in `EnvAgent`
- class `EnvAgentStatic` was removed, so there is only class `EnvAgent` left which should simplify the handling of agents. The member `self.agents_static` of `RailEnv` was therefore also removed. Old Scence saved as pickle files cannot be loaded anymore.
### Changes in malfunction behavior
- agent attribute `next_malfunction`is not used anymore, it will be removed fully in future versions.
- `break_agent()` function is introduced which induces malfunctions in agent according to poisson process
- `_fix_agent_after_malfunction()` fixes agents after attribute `malfunction == 0`
- Introduced the concept of malfunction generators. Here you can add different malfunction models in future updates. Currently it only loads from files and parameters.
### Changes in `Environment`
- moving of member variable `distance_map_computed` to new class `DistanceMap`
### Changes in rail generator and `RailEnv`
- renaming of `distance_maps` into `distance_map`
- by default the reset method of RailEnv is not called in the constructor of RailEnv anymore (compliance for OpenAI Gym). Therefore the reset method needs to be called after the creation of a RailEnv object
- renaming of parameters RailEnv.reset(): from `regen_rail` to `regenerate_rail`, from `replace_agents` to `regenerate_schedule`
### Changes in schedule generation
- return value of schedule generator has changed to the named tuple `Schedule`. From the point of view of a consumer, nothing has changed, this is just a type hint which is introduced where the attributes of `Schedule` have names.
Changes since Flatland 1.0.0
--------------------------
### Changes in stock predictors
The stock `ShortestPathPredictorForRailEnv` now respects the different agent speeds and updates their prediction accordingly.
### Changes in stock observation biulders
- `TreeObsForRailEnv` now has **11** features!
- 10th feature now indicates if a malfunctioning agent has been detected and how long the malfunction will still be present
- 11th feautre now indicates the minimal observed fractional speed of agents traveling in the same direction
- `GlobalObsForRailEnv` now has new features!
- Targets and other agent targets still represented in same way
- `obs_agents_state` now contains 4 channels
- 0th channel -> agent direction at agent position
- 1st channel -> other agents direction at their positions
- 2nd channel -> all agent malfunction duration at their positions
- 3rd channel -> all agent fractional speeds at their positions
- `LocalObsForRailEnv` was not update to Flatland 2.0 because it was never used by participants of the challenge.
### Changes in level generation
- Separation of `schedule_generator` from `rail_generator`:
- Renaming of `flatland/envs/generators.py` to `flatland/envs/rail_generators.py`
- `rail_generator` now only returns the grid and optionally hints (a python dictionary); the hints are currently use for distance_map and communication of start and goal position in complex rail generator.
- `schedule_generator` takes a `GridTransitionMap` and the number of agents and optionally the `agents_hints` field of the hints dictionary.
- Inrodcution of types hints:
```python
RailGeneratorProduct = Tuple[GridTransitionMap, Optional[Any]]
RailGenerator = Callable[[int, int, int, int], RailGeneratorProduct]
AgentPosition = Tuple[int, int]
ScheduleGeneratorProduct = Tuple[List[AgentPosition], List[AgentPosition], List[AgentPosition], List[float]]
ScheduleGenerator = Callable[[GridTransitionMap, int, Optional[Any]], ScheduleGeneratorProduct]
```
### Multi Speed
- Different agent speeds are introduced. Agents now travel at a max speed which is a fraction. Meaning that they only advance parts within a cell and need several steps to move to the next cell.
- Fastest speed is 1. At this speed an agent can move to a new cell at each time step t.
- Slower speeds are smaller than one. At each time step an agent moves the fraction of its speed forward within a cell. It only changes cell when it's fractional position is greater or equal to 1.
- Multi-speed introduces the challenge of ordering the trains correctly when traveling in the same direction.
- Agents always travel at their full speed when moving.
To set up multiple speeds you have to modify the `agent.speed_data` within your `schedule_generator`. See [this file](https://gitlab.aicrowd.com/flatland/flatland/blob/master/flatland/envs/schedule_generators.py#L59) for a good example.
**ATTENTION** multi speed means that the agents actions are not registered on every time step. Only at new cell entry can new actions be chosen! Beware to respect this with your controller as actions are only important at the specific time steps! This is shown as an example in the [navigation training](https://gitlab.aicrowd.com/flatland/baselines/blob/master/torch_training/training_navigation.py#L163)
### Stochastic events
Just like in real-worl transportation systems we introduced stochastic events to disturb normal traffic flow. Currently we implemented a malfunction process that stops agents at random time intervalls for a random time of duration.
Currently the Flatland environment can be initiated with the following poisson process parameters:
```python
# Use a the malfunction generator to break agents from time to time
stochastic_data = {'prop_malfunction': 0.1, # Percentage of defective agents
'malfunction_rate': 30, # Rate of malfunction occurence
'min_duration': 3, # Minimal duration of malfunction
'max_duration': 20 # Max duration of malfunction
}
```
The duration of a malfunction is uniformly drawn from the intervall `[min_duration,max_duration0]` and the occurance of malfunctions follows a point poisson process with mean rate `malfunctin_rate`.
**!!!!IMPORTANT!!!!** Once a malfunction duration has finished, the agent will **automatically** resume movement. This is important because otherwise it can get stuck in fractional positions and your code might forget to restart the agent at the first possible time. Therefore this has been automated. You can however stop the agent again at the next cell. This might in rare occasions lead to unexpected behavior, we are looking into this and will push a fix soon.
## Baselines repository
The baselines repository is not yet fully updated to handle multi-speed and stochastic events. Training needs to be modified to omitt all states inbetween the states where an agent can chose an action. Simple navigation training is already up to date. See [here](https://gitlab.aicrowd.com/flatland/baselines/blob/master/torch_training/training_navigation.py) for more details.
Changes since Flatland 0.2
--------------------------
Please list all major changes since the last version:
- Refactoring of rendering code: CamelCase functions changed to snake_case
- Tree Observation Added a new Featuer: `unusable_switch` which indicates switches that are not branchingpoints for the observing agent
- Updated the shortest path predictor
- Updated conflict detection with predictor
- Episodes length can be set as maximum number of steps allowed.
File added
File moved
.. include:: tutorials/01_gettingstarted.rst
.. include:: tutorials/02_observationbuilder.rst
.. include:: tutorials/03_rail_and_schedule_generator.rst
.. include:: tutorials/04_stochasticity.rst
.. include:: tutorials/05_multispeed.rst
.. include:: tutorials/06_round_2_starter_help.rst
Tutorials
=========
.. toctree::
:maxdepth: 2
03_tutorials
.. include:: specifications/intro.rst
.. include:: specifications/core.rst
.. include:: specifications/railway.rst
.. include:: specifications/intro_observation_actions.rst
.. include:: specifications/rendering.rst
.. include:: specifications/visualization.rst
Specifications
==============
.. toctree::
:maxdepth: 2
04_specifications
File moved
Changes
=======
.. toctree::
:maxdepth: 2
07_changes_include.rst
.. include:: ../changelog.rst
.. include:: ../flatland_2.0.rst
Authors
=======
.. include:: ../AUTHORS.rst
.. include:: ../FAQ_Challenge.rst
.. include:: ../FAQ_Repository.rst
.. include:: ../FAQ_Bugs.rst
FAQ
===
.. toctree::
:maxdepth: 2
09_faq
Multi-Agent Interface
=======
.. include:: interface/pettingzoo.rst
.. include:: interface/wrappers.rst
Multi-Agent Pettingzoo Usage
=======
We can use the PettingZoo interface by proving the rail env to the petting zoo wrapper as shown below in the example.
.. literalinclude:: ../tests/test_pettingzoo_interface.py
:language: python
:start-after: __sphinx_doc_begin__
:end-before: __sphinx_doc_end__
Multi-Agent Interface Stable Baseline 3 Training
=======
.. literalinclude:: ../flatland/contrib/training/flatland_pettingzoo_stable_baselines.py
:language: python
:start-after: __sphinx_doc_begin__
:end-before: __sphinx_doc_end__
Multi-Agent Interface Rllib Training
=======
.. literalinclude:: ../flatland/contrib/training/flatland_pettingzoo_rllib.py
:language: python
:start-after: __sphinx_doc_begin__
:end-before: __sphinx_doc_end__
\ No newline at end of file
Multi-Agent Interfaces
==============
.. toctree::
:maxdepth: 2
10_interface
========================================
Frequently Asked Questions (FAQs)
========================================
- I get a runtime error with `Click` complaining about the encoding
.. code-block:: python
RuntimeError('Click will abort further execution because Python 3 \
was configured to use ASCII as encoding for ...sk_SK.UTF-8, \
sl_SI.UTF-8, sr_YU.UTF-8, sv_SE.UTF-8, tr_TR.UTF-8, \
uk_UA.UTF-8, zh_CN.UTF-8, zh_HK.UTF-8, zh_TW.UTF-8')
This can be solved by :
.. code-block:: bash
export LC_ALL=en_US.utf-8
export LANG=en_US.utf-8
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
# TODO fix sphinx warnings instead of suppressing them...
SPHINXOPTS = -Q
SPHINXBUILD = python -msphinx
SPHINXPROJ = flatland
SOURCEDIR = .
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)