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 2251 additions and 372 deletions
%% Cell type:markdown id: tags:
# Test Service
Intended to test the service.py evaluator.
Runs the service.py and a simple client.
%% Cell type:markdown id: tags:
Setup
---
%% Cell type:code id: tags:
``` python
%load_ext autoreload
%autoreload 2
```
%% Cell type:code id: tags:
``` python
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:90% !important; }</style>"))
```
%% Cell type:code id: tags:
``` python
import os
import redis
import subprocess as sp
import shlex
import time
```
%% Cell type:code id: tags:
``` python
import numpy as np
```
%% Cell type:code id: tags:
``` python
from flatland.core.env_observation_builder import DummyObservationBuilder
from flatland.envs.persistence import RailEnvPersister
from flatland.evaluators.client import FlatlandRemoteClient
from flatland.evaluators.client import TimeoutException
```
%% Cell type:code id: tags:
``` python
sDirRoot = "/Users/flaurent/Sites/flatland/neurips2020-flatland-starter-kit/scratch/test-neurips2020-round2-v0"
```
%% Cell type:code id: tags:
``` python
!ps -ef | grep -i python | grep -i flatland.evaluators.service
```
%% Cell type:code id: tags:
``` python
def kill_evaluator():
# kill previous evaluator
!ps -ef | grep -i python | grep -i flatland.evaluators.service | awk '{print $2}' | xargs kill
```
%% Cell type:code id: tags:
``` python
def cleanup():
oRedis = redis.Redis()
lKeys = oRedis.keys("flatland*")
for sKey in lKeys:
print("Deleting:", sKey)
oRedis.delete(sKey)
!rm -f /tmp/output.csv
kill_evaluator()
```
%% Cell type:code id: tags:
``` python
def configure_env(overall=8*60*60, planning=5*60, step=10, successive=10, mean_percentage=0.25):
osEnv2 = os.environ.copy()
osEnv2["FLATLAND_OVERALL_TIMEOUT"]=str(overall)
osEnv2["FLATLAND_PER_STEP_TIMEOUT"] = str(step)
osEnv2["FLATLAND_INITIAL_PLANNING_TIMEOUT"] = str(planning)
osEnv2["FLATLAND_MAX_SUCCESSIVE_TIMEOUTS"] = str(successive)
osEnv2["TEST_MIN_PERCENTAGE_COMPLETE_MEAN"] = str(mean_percentage)
return osEnv2
```
%% Cell type:code id: tags:
``` python
def start_evaluator(env):
sCmd = f"python -m flatland.evaluators.service --test_folder {sDirRoot} --pickle" # --verbose"
lsCmd = shlex.split(sCmd)
print(sCmd)
oPipe = sp.Popen(lsCmd, env=env)
oPipe.poll()
```
%% Cell type:code id: tags:
``` python
def start_client():
oFRC = FlatlandRemoteClient(test_envs_root=sDirRoot, verbose=False, use_pickle=True)
env, env_dict = RailEnvPersister.load_new(f"{sDirRoot}/Test_0/Level_0.pkl")
return oFRC
```
%% Cell type:code id: tags:
``` python
def random_controller(obs, _env):
np.random.seed(0)
dAct = {}
for iAg in range(len(_env.agents)):
dAct[iAg] = np.random.randint(0, 5)
return dAct
```
%% Cell type:code id: tags:
``` python
def run_submission(oFRC, slow_ep=-1, debug=False):
def log(txt, end="\n"):
if debug: print(txt, end)
dummy_obs = DummyObservationBuilder()
episode = 0
obs = True
while obs:
obs, info = oFRC.env_create(obs_builder_object=dummy_obs)
log(oFRC.current_env_path)
log(f"Episode : {episode}")
if not obs:
log("None observation - all envs completed!")
break
while True:
action = random_controller(obs, oFRC.env)
if slow_ep != -1:
# make a specific episode artificially slow
if (episode == slow_ep) and (oFRC.env._elapsed_steps > 10):
time.sleep(2)
try:
observation, all_rewards, done, info = oFRC.env_step(action)
#log(".", end="")
if done['__all__']:
log("\nCompleted Episode : ", episode)
log("Reward : ", sum(list(all_rewards.values())))
break
except TimeoutException as err:
log("Timeout: ", err)
break
episode += 1
```
%% Cell type:markdown id: tags:
Tests
---
%% Cell type:code id: tags:
``` python
%%time
# Normal submission
cleanup()
config = configure_env(overall=8*60*60, planning=5*60, step=10, successive=10, mean_percentage=0.1)
start_evaluator(config)
client = start_client()
run_submission(client)
```
%% Cell type:code id: tags:
``` python
%%time
# Overall timeout
cleanup()
config = configure_env(overall=3, planning=5*60, step=10, successive=10, mean_percentage=0.0)
start_evaluator(config)
client = start_client()
run_submission(client, debug=False)
```
%% Cell type:markdown id: tags:
Cleanup
---
%% Cell type:code id: tags:
``` python
kill_evaluator()
```
%% Cell type:markdown id: tags:
# Rail Editor v0.2
## Load some (old) env files to check they work
This notebook just loads some old env files, renders them, and runs a few steps.
This is just a sanity check that these old envs will still load.
Many of them use deprecated data formats so it's just so that we can avoid deleting them for now, and so new participants are not confused by us shipping env files which don't work...
%% Cell type:code id: tags:
``` python
%load_ext autoreload
%autoreload 2
```
%% Cell type:code id: tags:
``` python
import numpy as np
from numpy import array
import ipywidgets
import IPython
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:90% !important; }</style>"))
```
%% Cell type:code id: tags:
``` python
display(HTML("<style>.container { width:95% !important; }</style>"))
import importlib_resources as ir
```
%% Output
%% Cell type:code id: tags:
``` python
from flatland.utils.editor import EditorMVC, EditorModel, View, Controller
from flatland.envs.persistence import RailEnvPersister
from flatland.utils import jupyter_utils as ju
```
%% Output
cpu
%% Cell type:code id: tags:
``` python
mvc = EditorMVC(sGL="PIL" ) # sGL="PIL")
lsPackages = [ "env_data.railway"]
```
%% Output
%% Cell type:markdown id: tags:
## Instructions
- Drag to draw
- improved dead-ends
- Shift-Drag to erase rails
- erasing dead ends not yet automated - drag right across them
- ctrl-click to add agent
- direction chosen randomly to fit rail
- ctrl-shift-click to add target for last agent
- target can be moved by repeating
%% Cell type:code id: tags:
``` python
mvc.view.display()
ltPackRes = []
for sPack in lsPackages:
for sExt in ["mpk", "pkl"]:
ltPackRes += [ (sPack, sRes) for sRes in ir.contents(sPack) if sRes.endswith(sExt) ]
ltPackRes
```
%% Output
%% Cell type:code id: tags:
``` python
mvc.view.wOutput.clear_output()
mvc.view.wOutput
for sPack, sRes in ltPackRes:
print("Loading: ", sPack, sRes)
env, env_dict = RailEnvPersister.load_new(sRes, load_from_package=sPack)
env.reset()
oCanvas = ju.EnvCanvas(env, ju.AlwaysForward(env))
oCanvas.show()
for iStep in range(10):
oCanvas.step()
oCanvas.render()
```
%% Output
......
%% Cell type:markdown id: tags:
# Test Service
Intended to test the service.py evaluator.
Runs the service.py and a simple client.
%% Cell type:markdown id: tags:
# Setup
%% Cell type:code id: tags:
``` python
%load_ext autoreload
%autoreload 2
```
%% Cell type:code id: tags:
``` python
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:90% !important; }</style>"))
```
%% Cell type:code id: tags:
``` python
import sys
import os
import redis
import subprocess as sp
import shlex
import time
import importlib_resources as ir
```
%% Cell type:code id: tags:
``` python
import pandas as pd
import numpy as np
```
%% Cell type:code id: tags:
``` python
from flatland.core.env_observation_builder import DummyObservationBuilder
from flatland.envs.persistence import RailEnvPersister
from flatland.evaluators.client import FlatlandRemoteClient
from flatland.evaluators.client import TimeoutException
from flatland.envs.rail_env import RailEnvActions
```
%% Cell type:markdown id: tags:
### Find the real path of the `env_data` package (should be copied by tox)
%% Cell type:code id: tags:
``` python
with ir.path("env_data.tests", "test_001.pkl") as oPath:
sPath = oPath
print(type(sPath), sPath)
```
%% Cell type:code id: tags:
``` python
sDirRoot = "/" + "/".join(sPath.parts[1:-1] + ("service_test",""))
sDirRoot
```
%% Cell type:markdown id: tags:
### Clear any old redis keys
%% Cell type:code id: tags:
``` python
oRedis = redis.Redis()
```
%% Cell type:code id: tags:
``` python
lKeys = oRedis.keys("flatland*")
lKeys
```
%% Cell type:code id: tags:
``` python
for sKey in lKeys:
print("Deleting:", sKey)
oRedis.delete(sKey)
```
%% Cell type:markdown id: tags:
### Remove `/tmp/output.csv`
%% Cell type:code id: tags:
``` python
!rm -f /tmp/output.csv
```
%% Cell type:markdown id: tags:
### kill any old `service.py` process
%% Cell type:code id: tags:
``` python
!ps -ef | grep -i python | grep -i flatland.evaluators.service | awk '{print $2}' | xargs kill
```
%% Cell type:code id: tags:
``` python
osEnv2 = os.environ.copy()
```
%% Cell type:markdown id: tags:
### Set some short timeouts for testing
%% Cell type:code id: tags:
``` python
osEnv2["FLATLAND_OVERALL_TIMEOUT"]="10"
osEnv2["FLATLAND_PER_STEP_TIMEOUT"] = "2"
osEnv2["FLATLAND_MAX_SUCCESSIVE_TIMEOUTS"] = "2"
```
%% Cell type:markdown id: tags:
### Create the python command for `service.py`
%% Cell type:code id: tags:
``` python
#sCmd = "python -m flatland.evaluators.service --test_folder ../env_data/tests/service_test --mergeDir ./tmp/merge --actionDir ./tmp/actions --pickle --missingOnly"
#sCmd = "python -m flatland.evaluators.service --test_folder ../env_data/tests/service_test --pickle" # --verbose"
sCmd = f"python -m flatland.evaluators.service --test_folder {sDirRoot} --pickle" # --verbose"
lsCmd = shlex.split(sCmd)
print(sCmd)
print(lsCmd)
```
%% Cell type:markdown id: tags:
### Run the command with Popen (output goes to jupyter stdout not notebook)
%% Cell type:code id: tags:
``` python
oPipe = sp.Popen(lsCmd, env=osEnv2)
```
%% Cell type:code id: tags:
``` python
oPipe.poll()
```
%% Cell type:code id: tags:
``` python
oFRC = FlatlandRemoteClient(test_env_folder=sDirRoot, verbose=False, use_pickle=True)
```
%% Cell type:code id: tags:
``` python
env, env_dict = RailEnvPersister.load_new(f"{sDirRoot}/Test_0/Level_0.pkl")
```
%% Cell type:code id: tags:
``` python
def forward_only_controller(obs, _env):
dAct = {}
for iAg in range(len(_env.agents)):
dAct[iAg] = RailEnvActions.MOVE_FORWARD
return dAct
def random_controller(obs, _env):
dAct = {}
for iAg in range(len(_env.agents)):
dAct[iAg] = np.random.randint(0, 5)
return dAct
```
%% Cell type:code id: tags:
``` python
oObsB = DummyObservationBuilder()
```
%% Cell type:code id: tags:
``` python
oObsB.get()
```
%% Cell type:code id: tags:
``` python
def run_submission(slow_ep=1, delay=2):
episode = 0
obs = True
while obs:
obs, info = oFRC.env_create(obs_builder_object=oObsB)
if not obs:
print("null observation - all envs completed!")
break
print(f"Episode : {episode}")
print(oFRC.env.dones['__all__'])
while True:
if episode < 3:
action = forward_only_controller(obs, oFRC.env)
else:
action = random_controller(obs, oFRC.env)
time_start = time.time()
if (episode == slow_ep) and (oFRC.env._elapsed_steps > 10):
time.sleep(2)
try:
observation, all_rewards, done, info = oFRC.env_step(action)
time_diff = time.time() - time_start
print(".", end="")
if done['__all__']:
print("\nCompleted Episode : ", episode)
print("Reward : ", sum(list(all_rewards.values())))
break
except TimeoutException as err:
print("Timeout: ", err)
break
episode += 1
print(f"Evaluation Complete - episodes={episode} - send submit message...")
print(oFRC.submit())
print("All done.")
```
%% Cell type:code id: tags:
``` python
try:
run_submission()
except TimeoutException as timeoutException:
print("Timed out.")
print(timeoutException)
```
%% Cell type:markdown id: tags:
### Kill the evaluator process we started earlier
%% Cell type:code id: tags:
``` python
!ps -ef | grep -i python | grep -i flatland.evaluators.service | awk '{print $2}' | xargs kill
```
%% Cell type:code id: tags:
``` python
pd.read_csv("/tmp/output.csv").T
```
ffmpeg -y -framerate 12 -i frame_%04d.bmp -hide_banner -c:v libx264 -pix_fmt yuv420p test.mp4
ffmpeg -i test.mp4 test.gif
pause
\ No newline at end of file
# contains all additional requirements to run the ```tox .``` in addition to requirements_dev.txt for ```tox -e py36,py37```
bumpversion>=0.5.3
wheel>=0.32.1
watchdog>=0.9.0
benchmarker>=4.0.1
coverage>=4.5.1
# pin sphinx to <2.0 because of https://github.com/readthedocs/sphinx_rtd_theme/issues/746
Sphinx>=1.8.1,<2.0
sphinx-rtd-theme>=0.4.3
numpydoc>=0.9.1
docutils>=0.15.2
flake8>=3.7.7
flake8-eradicate>=0.2.0
twine>=1.12.1
pydeps>=1.7.2
jupyter>=1.0.0
jupyter-core>=4.5.0
jupyter-contrib-nbextensions
notebook>=5.7.8
PyVirtualDisplay==1.3.2
pytest-xvfb==2.0.0
git+https://github.com/who8mylunch/Jupyter_Canvas_Widget.git@bd151ae1509c50b5809944dd3294f58b7b069c86
m2r>=0.2.1
bumpversion==0.5.3
wheel==0.32.1
watchdog==0.9.0
flake8==3.5.0
tox==3.5.2
coverage==4.5.1
Sphinx==1.8.1
twine==1.12.1
pytest==3.8.2
pytest-runner==4.2
sphinx-rtd-theme==0.4.3
numpy==1.16.2
recordtype==1.3
xarray==0.11.3
matplotlib==3.0.2
PyQt5==5.12
Pillow==5.4.1
# contains all requirements to run the tests by running ```tox -e py36,py37```
tox>=3.5.2
pytest>=3.8.2,<5
pytest-runner>=4.2
Click>=7.0
crowdai-api>=0.1.21
numpy>=1.16.2
recordtype>=1.3
matplotlib>=3.0.2
Pillow>=5.4.1
msgpack>=1.0.0,<2.0.0
msgpack-numpy>=0.4.4.0
svgutils>=0.3.1
pyarrow>=0.13.0
pandas>=0.25.1
importlib-metadata>=0.17
importlib-resources>=1.0.1,<2
six>=1.12.0
timeout-decorator>=0.4.1
attrs
gym==0.14.0
networkx
ipycanvas
graphviz
imageio
dataclasses
from flatland.envs.agent_utils import TrainState
from flatland.envs.malfunction_generators import ParamMalfunctionGen
from flatland.envs.malfunction_generators import MalfunctionParameters
from flatland.envs.observations import GlobalObsForRailEnv
from flatland.envs.rail_env import RailEnv
from flatland.envs.rail_generators import sparse_rail_generator
from flatland.envs.line_generators import sparse_line_generator
import random
import r2_solver
import sys
import time
import matplotlib.pyplot as plt
import PIL
from flatland.utils.rendertools import RenderTool
from IPython.display import clear_output
from IPython.display import display
def GetTestParams(tid):
seed = tid * 19997 + 997
random.seed(seed)
width = 30 + random.randint(0, 11)
height = 30 + random.randint(0, 11)
nr_cities = 4 + random.randint(0, (width + height) // 10)
nr_trains = min(nr_cities * 4, 10 + random.randint(0, 10))
max_rails_between_cities = 2
max_rails_in_cities = 3 + random.randint(0, 5)
malfunction_rate = 0#1/100 + random.randint(0, 5)
malfunction_min_duration = 0#1 + random.randint(0, 5)
malfunction_max_duration = 0#6 + random.randint(0, 10)
return (seed, width, height, nr_trains, nr_cities, max_rails_between_cities, max_rails_in_cities, malfunction_rate,
malfunction_min_duration, malfunction_max_duration)
def render_env(env,wait=True,cnt=0):
env_renderer = RenderTool(env, gl="PILSVG")
env_renderer.render_env()
image = env_renderer.get_image()
pil_image = PIL.Image.fromarray(image)
# clear_output(wait=True)
pil_image.save("images/"+str(cnt)+".png")
def ShouldRunTest(tid):
# return tid == 5
# return tid >= 3
return True
DEFAULT_SPEED_RATIO_MAP = {1.: 0.25,
1. / 2.: 0.25,
1. / 3.: 0.25,
1. / 4.: 0.25}
NUM_TESTS = 200
d_base = {}
# f = open("scores.txt", "r")
# for line in f.readlines():
# lsplit = line.split(" ")
# if len(lsplit) >= 4:
# test_id = int(lsplit[0])
# num_done_agents = int(lsplit[1])
# percentage_num_done_agents = float(lsplit[2])
# score = float(lsplit[3])
# d_base[test_id] = (num_done_agents, score)
# f.close()
f = open("tmp-scores.txt", "w")
total_percentage_num_done_agents = 0.0
total_score = 0.0
total_base_percentage_num_done_agents = 0.0
total_base_score = 0.0
num_tests = 0
cnt = 0
for test_id in range(NUM_TESTS):
print(test_id)
seed, width, height, nr_trains, nr_cities, max_rails_between_cities, max_rails_in_cities, malfunction_rate, \
malfunction_min_duration, malfunction_max_duration = GetTestParams(test_id)
if not ShouldRunTest(test_id):
continue
rail_generator = sparse_rail_generator(max_num_cities=nr_cities,
seed=seed,
grid_mode=False,
max_rails_between_cities=max_rails_between_cities,
max_rail_pairs_in_city=max_rails_in_cities,
)
line_generator = sparse_line_generator(DEFAULT_SPEED_RATIO_MAP, seed=seed)
stochastic_data = MalfunctionParameters(malfunction_rate = malfunction_rate,
min_duration = malfunction_min_duration,
max_duration = malfunction_max_duration,
)
observation_builder = GlobalObsForRailEnv()
env = RailEnv(width=width,
height=height,
rail_generator=rail_generator,
line_generator=line_generator,
number_of_agents=nr_trains,
malfunction_generator=ParamMalfunctionGen(stochastic_data),
obs_builder_object=observation_builder,
remove_agents_at_target=True,
random_seed=seed
)
obs = env.reset()
render_env(env)
solver = r2_solver.Solver(test_id)
score = 0.0
num_steps = 15 * (width + height)
all_rewards = {}
print(
"test_id=%d seed=%d nr_trains=%d nr_cities=%d num_steps=%d" % (test_id, seed, nr_trains, nr_cities, num_steps))
for step in range(num_steps):
moves = solver.GetMoves(env.agents, obs[0], env.distance_map, env._max_episode_steps)
next_obs, all_rewards, done, _ = env.step(moves)
# render_env(env, True, cnt)
cnt += 1
# print("step",cnt)
for a in range(env.get_num_agents()):
score += float(all_rewards[a])
obs = next_obs.copy()
if done['__all__']:
break
# print(env._elapsed_steps)
# for a in range(env.get_num_agents()):
# print(a, float(all_rewards[a]))
print("--Reward : ", sum(list(all_rewards.values())))
num_done_agents = 0
for aid, agent in enumerate(env.agents):
if agent.state == TrainState.DONE:
num_done_agents += 1
percentage_num_done_agents = 100.0 * num_done_agents / len(env.agents)
total_percentage_num_done_agents += percentage_num_done_agents
total_score += score
num_tests += 1
base_num_done_agents = 0
base_score = -1e9
if test_id in d_base:
base_num_done_agents, base_score = d_base[test_id]
base_percentage_num_done_agents = 100.0 * base_num_done_agents / len(env.agents)
total_base_percentage_num_done_agents += base_percentage_num_done_agents
total_base_score += base_score
avg_nda = total_percentage_num_done_agents / num_tests
avg_nda_dif = (total_percentage_num_done_agents - total_base_percentage_num_done_agents) / num_tests
print(
"\n### test_id=%d nda=%d(dif=%d) pnda=%.6f(dif=%.6f) score=%.6f(dif=%.6f) avg_nda=%.6f(dif=%.6f) avg_sc=%.6f(dif=%.6f)\n" % (
test_id, num_done_agents, num_done_agents - base_num_done_agents, percentage_num_done_agents,
percentage_num_done_agents - base_percentage_num_done_agents, score, score - base_score, avg_nda, avg_nda_dif,
total_score / num_tests, (total_score - total_base_score) / num_tests))
f.write("%d %d% .10f %.10f %d %.10f %.10f\n" % (
test_id, num_done_agents, percentage_num_done_agents, score, num_done_agents - base_num_done_agents,
percentage_num_done_agents - base_percentage_num_done_agents, avg_nda_dif))
f.flush()
# f.close()
from flatland.envs.agent_utils import TrainState
from flatland.envs.malfunction_generators import ParamMalfunctionGen
from flatland.envs.malfunction_generators import MalfunctionParameters
from flatland.envs.observations import GlobalObsForRailEnv
from flatland.envs.rail_env import RailEnv
from flatland.envs.rail_generators import sparse_rail_generator
from flatland.envs.line_generators import sparse_line_generator
from flatland.envs.rail_env_action import RailEnvActions
import random
# import r2_solver
import sys
import time
import matplotlib.pyplot as plt
import PIL
from flatland.utils.rendertools import RenderTool
from IPython.display import clear_output
from IPython.display import display
def GetTestParams(tid):
seed = tid * 19997 + 997
random.seed(seed)
width = 30 + random.randint(0, 11)
height = 30 + random.randint(0, 11)
nr_cities = 4 + random.randint(0, (width + height) // 10)
nr_trains = min(nr_cities * 4, 10 + random.randint(0, 10))
max_rails_between_cities = 2
max_rails_in_cities = 3 + random.randint(0, 5)
malfunction_rate = 0#1/100 + random.randint(0, 5)
malfunction_min_duration = 0#1 + random.randint(0, 5)
malfunction_max_duration = 0#6 + random.randint(0, 10)
return (seed, width, height, nr_trains, nr_cities, max_rails_between_cities, max_rails_in_cities, malfunction_rate,
malfunction_min_duration, malfunction_max_duration)
def render_env(env,wait=True,cnt=0):
return
env_renderer = RenderTool(env, gl="PILSVG")
env_renderer.render_env()
image = env_renderer.get_image()
pil_image = PIL.Image.fromarray(image)
# clear_output(wait=True)
pil_image.save("images/"+str(cnt)+".png")
def ShouldRunTest(tid):
return tid >= 7
# return tid >= 3
return True
def getactions(step):
with open('/Users/dipam/Downloads/actions_ms.txt', 'r') as f:
line = f.readline()
while line.strip() != f'time= {step}':
line = f.readline()
_ = f.readline()
actions = {}
line = f.readline()
while line.strip().split(' ')[0] != 'time=':
lsplit = line.strip().split(' ')
act = int(lsplit[-1])
i_agent = int(lsplit[0])
actions[i_agent] = act
line = f.readline()
return actions
DEFAULT_SPEED_RATIO_MAP = {1.: 0.25,
1. / 2.: 0.25,
1. / 3.: 0.25,
1. / 4.: 0.25}
NUM_TESTS = 1
d_base = {}
# f = open("scores.txt", "r")
# for line in f.readlines():
# lsplit = line.split(" ")
# if len(lsplit) >= 4:
# test_id = int(lsplit[0])
# num_done_agents = int(lsplit[1])
# percentage_num_done_agents = float(lsplit[2])
# score = float(lsplit[3])
# d_base[test_id] = (num_done_agents, score)
# f.close()
# f = open("tmp-scores.txt", "w")
total_percentage_num_done_agents = 0.0
total_score = 0.0
total_base_percentage_num_done_agents = 0.0
total_base_score = 0.0
num_tests = 0
cnt = 0
for test_id in range(NUM_TESTS):
seed, width, height, nr_trains, nr_cities, max_rails_between_cities, max_rails_in_cities, malfunction_rate, \
malfunction_min_duration, malfunction_max_duration = GetTestParams(test_id)
# if not ShouldRunTest(test_id):
# continue
rail_generator = sparse_rail_generator(max_num_cities=nr_cities,
seed=seed,
grid_mode=False,
max_rails_between_cities=max_rails_between_cities,
max_rail_pairs_in_city=max_rails_in_cities,
)
line_generator = sparse_line_generator(DEFAULT_SPEED_RATIO_MAP, seed=seed)
stochastic_data = MalfunctionParameters(malfunction_rate = malfunction_rate,
min_duration = malfunction_min_duration,
max_duration = malfunction_max_duration,
)
# stochastic_data = MalfunctionParameters(
# malfunction_rate=1/10000, # Rate of malfunction occurence
# min_duration=15, # Minimal duration of malfunction
# max_duration=50 # Max duration of malfunction
# )
observation_builder = GlobalObsForRailEnv()
env = RailEnv(width=width,
height=height,
rail_generator=rail_generator,
line_generator=line_generator,
number_of_agents=nr_trains,
malfunction_generator=ParamMalfunctionGen(stochastic_data),
obs_builder_object=observation_builder,
remove_agents_at_target=True,
random_seed=seed
)
obs = env.reset()
render_env(env)
# solver = r2_solver.Solver(test_id)
score = 0.0
num_steps = 80 * (width + height + 20)
print(
"test_id=%d seed=%d nr_trains=%d nr_cities=%d num_steps=%d" % (test_id, seed, nr_trains, nr_cities, num_steps))
for step in range(num_steps):
# moves = solver.GetMoves(env.agents, obs[0])
moves = getactions(step)
if env.agents[1].speed_counter.is_cell_exit:
moves[1] = 4
if env._elapsed_steps > 25 and env._elapsed_steps < 41:
a1 = env.agents[1]
a5 = env.agents[5]
print("Step", env._elapsed_steps, "Agent 1", a1.position, a1.state, a1.speed_counter.counter, moves[1],
env.agents[1].speed_counter.is_cell_exit, env.agents[1].speed_counter.counter)
next_obs, all_rewards, done, _ = env.step(moves)
old_agent_positions = env.agent_positions.copy()
# for ag in self.agents:
# if ag.state == TrainState.STOPPED and ag.state_machine.previous_state == TrainState.MALFUNCTION_OFF_MAP and \
# action_dict_.get(ag.handle, 4) == RailEnvActions.DO_NOTHING:
# import pdb; pdb.set_trace()
positions = {}
for ag in env.agents:
if ag.position in positions:
import pdb; pdb.set_trace()
if ag.position is not None:
positions[ag.position] = ag.handle, ag.speed_counter.speed
# if env._elapsed_steps > 30:
# import pdb; pdb.set_trace()
render_env(env, True, cnt)
cnt += 1
for a in range(env.get_num_agents()):
score += float(all_rewards[a])
obs = next_obs.copy()
if done['__all__']:
break
num_done_agents = 0
for aid, agent in enumerate(env.agents):
if agent.state == TrainState.DONE:
num_done_agents += 1
percentage_num_done_agents = 100.0 * num_done_agents / len(env.agents)
total_percentage_num_done_agents += percentage_num_done_agents
total_score += score
num_tests += 1
base_num_done_agents = 0
base_score = -1e9
if test_id in d_base:
base_num_done_agents, base_score = d_base[test_id]
base_percentage_num_done_agents = 100.0 * base_num_done_agents / len(env.agents)
total_base_percentage_num_done_agents += base_percentage_num_done_agents
total_base_score += base_score
avg_nda = total_percentage_num_done_agents / num_tests
avg_nda_dif = (total_percentage_num_done_agents - total_base_percentage_num_done_agents) / num_tests
# print(
# "\n### test_id=%d nda=%d(dif=%d) pnda=%.6f(dif=%.6f) score=%.6f(dif=%.6f) avg_nda=%.6f(dif=%.6f) avg_sc=%.6f(dif=%.6f)\n" % (
# test_id, num_done_agents, num_done_agents - base_num_done_agents, percentage_num_done_agents,
# percentage_num_done_agents - base_percentage_num_done_agents, score, score - base_score, avg_nda, avg_nda_dif,
# total_score / num_tests, (total_score - total_base_score) / num_tests))
# f.write("%d %d% .10f %.10f %d %.10f %.10f\n" % (
# test_id, num_done_agents, percentage_num_done_agents, score, num_done_agents - base_num_done_agents,
# percentage_num_done_agents - base_percentage_num_done_agents, avg_nda_dif))
# f.flush()
# f.close()
#!/usr/bin/env python
import glob
from cairosvg import svg2png
import os
import shutil
import tqdm
import io
from PIL import Image
########################################################
########################################################
#
# Converts SVG assets into PNG assets
#
# We use this approach to drop the CairoSVG dependency
# from the flatland requirements.
#
# Usage Requires :
#
# conda install cairo
#
########################################################
########################################################
TARGET_PNG_WIDTH=300
TARGET_PNG_HEIGHT=300
SVG_FOLDER="../flatland/svg"
TARGET_FOLDER="../flatland/png"
# Delete target PNG files, if they exist
for _png_file in glob.glob(os.path.join(TARGET_FOLDER, "*.png")):
os.remove(_png_file)
# Convert all SVG files into PNG files
for _source_svg_path in tqdm.tqdm(glob.glob(os.path.join(SVG_FOLDER, "*.svg"))):
base_filename = os.path.basename(_source_svg_path)
target_filename = base_filename.replace(".svg", ".png")
target_filepath = os.path.join(
TARGET_FOLDER,
target_filename
)
bytesPNG = svg2png(
file_obj=open(_source_svg_path, "rb"),
output_height=TARGET_PNG_WIDTH,
output_width=TARGET_PNG_HEIGHT
)
with io.BytesIO(bytesPNG) as fIn:
im = Image.open(fIn)
im.load()
assert im.size == (TARGET_PNG_WIDTH, TARGET_PNG_HEIGHT)
im.save(target_filepath)
[bumpversion]
current_version = 0.1.1
current_version = 3.0.15
commit = True
tag = True
......@@ -22,4 +22,3 @@ test = pytest
[tool:pytest]
collect_ignore = ['setup.py']
......@@ -2,26 +2,58 @@
# -*- coding: utf-8 -*-
"""The setup script."""
import os
import sys
from setuptools import setup, find_packages
with open('README.rst') as readme_file:
assert sys.version_info >= (3, 6)
with open('README.md', 'r', encoding='utf8') as readme_file:
readme = readme_file.read()
with open('HISTORY.rst') as history_file:
history = history_file.read()
requirements = ['Click>=6.0', ]
def get_all_svg_files(directory='./svg/'):
ret = []
for dirpath, subdirs, files in os.walk(directory):
for f in files:
ret.append(os.path.join(dirpath, f))
return ret
setup_requirements = ['pytest-runner', ]
test_requirements = ['pytest', ]
def get_all_images_files(directory='./images/'):
ret = []
for dirpath, subdirs, files in os.walk(directory):
for f in files:
ret.append(os.path.join(dirpath, f))
return ret
def get_all_notebook_files(directory='./notebooks/'):
ret = []
for dirpath, subdirs, files in os.walk(directory):
for f in files:
ret.append(os.path.join(dirpath, f))
return ret
# Gather requirements from requirements_dev.txt
install_reqs = []
requirements_path = 'requirements_dev.txt'
with open(requirements_path, 'r') as f:
install_reqs += [
s for s in [
line.strip(' \n') for line in f
] if not s.startswith('#') and s != ''
]
requirements = install_reqs
setup_requirements = install_reqs
test_requirements = install_reqs
setup(
author="S.P. Mohanty",
author_email='mohanty@aicrowd.com',
classifiers=[
'Development Status :: 2 - Pre-Alpha',
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'Natural Language :: English',
'Programming Language :: Python :: 3.6',
......@@ -30,19 +62,24 @@ setup(
description="Multi Agent Reinforcement Learning on Trains",
entry_points={
'console_scripts': [
'flatland=flatland.cli:main',
'flatland-demo=flatland.cli:demo',
'flatland-evaluator=flatland.cli:evaluator'
],
},
install_requires=requirements,
long_description=readme + '\n\n' + history,
long_description=readme,
long_description_content_type="text/markdown",
include_package_data=True,
keywords='flatland',
name='flatland-rl',
packages=find_packages('.'),
data_files=[('svg', get_all_svg_files()),
('images', get_all_images_files()),
('notebooks', get_all_notebook_files())],
setup_requires=setup_requirements,
test_suite='tests',
tests_require=test_requirements,
url='https://gitlab.aicrowd.com/flatland/flatland',
version='0.1.1',
version='3.0.15',
zip_safe=False,
)
source diff could not be displayed: it is too large. Options to address this: view the blob.
#!/bin/bash
export FLATLAND_DEFAULT_COMMAND_TIMEOUT=5
export FLATLAND_DEFAULT_COMMAND_TIMEOUT=60
export FLATLAND_INITIAL_PLANNING_TIMEOUT=8
export AICROWD_TESTS_FOLDER=../submission-scoring/Envs/neurips2020_round1_v0
redis-cli KEYS "*" | grep -i flatland | xargs redis-cli DEL
# you need to create the envs in the folder
# best to delete all but 10 small ones
#gnome-terminal --title Service --window -- python -m flatland.evaluators.service --test_folder ../submission-scoring/Envs/neurips2020_round1_v0/
xterm -title Service -hold -e "python -m flatland.evaluators.service --test_folder ../submission-scoring/Envs/neurips2020_round1_v0/ " &
#gnome-terminal --title test_eval_timeout --window -- python tests/test_eval_timeout.py
xterm -title test_eval_timeout -hold -e "python tests/test_eval_timeout.py" &
from flatland.action_plan.action_plan import TrainrunWaypoint, ActionPlanElement, \
ControllerFromTrainruns
from flatland.action_plan.action_plan_player import ControllerFromTrainrunsReplayer
from flatland.core.grid.grid4 import Grid4TransitionsEnum
from flatland.envs.observations import GlobalObsForRailEnv
from flatland.envs.rail_env import RailEnv, RailEnvActions
from flatland.envs.rail_generators import rail_from_grid_transition_map
from flatland.envs.rail_trainrun_data_structures import Waypoint
from flatland.envs.line_generators import sparse_line_generator
from flatland.utils.rendertools import RenderTool, AgentRenderVariant
from flatland.utils.simple_rail import make_simple_rail
from flatland.envs.step_utils.speed_counter import SpeedCounter
def test_action_plan(rendering: bool = False):
"""Tests ActionPlanReplayer: does action plan generation and replay work as expected."""
rail, rail_map, optionals = make_simple_rail()
env = RailEnv(width=rail_map.shape[1],
height=rail_map.shape[0],
rail_generator=rail_from_grid_transition_map(rail, optionals),
line_generator=sparse_line_generator(seed=77),
number_of_agents=2,
obs_builder_object=GlobalObsForRailEnv(),
remove_agents_at_target=True,
random_seed=1,
)
env.reset()
env.agents[0].initial_position = (3, 0)
env.agents[0].target = (3, 8)
env.agents[0].initial_direction = Grid4TransitionsEnum.WEST
env.agents[1].initial_position = (3, 8)
env.agents[1].initial_direction = Grid4TransitionsEnum.WEST
env.agents[1].target = (0, 3)
env.agents[1].speed_counter = SpeedCounter(speed=0.5)
env.reset(False, False)
for handle, agent in enumerate(env.agents):
print("[{}] {} -> {}".format(handle, agent.initial_position, agent.target))
# Perform DO_NOTHING actions until all trains get to READY_TO_DEPART
for _ in range(max([agent.earliest_departure for agent in env.agents]) + 1):
env.step({}) # DO_NOTHING for all agents
chosen_path_dict = {0: [TrainrunWaypoint(scheduled_at=0, waypoint=Waypoint(position=(3, 0), direction=3)),
TrainrunWaypoint(scheduled_at=2, waypoint=Waypoint(position=(3, 1), direction=1)),
TrainrunWaypoint(scheduled_at=3, waypoint=Waypoint(position=(3, 2), direction=1)),
TrainrunWaypoint(scheduled_at=14, waypoint=Waypoint(position=(3, 3), direction=1)),
TrainrunWaypoint(scheduled_at=15, waypoint=Waypoint(position=(3, 4), direction=1)),
TrainrunWaypoint(scheduled_at=16, waypoint=Waypoint(position=(3, 5), direction=1)),
TrainrunWaypoint(scheduled_at=17, waypoint=Waypoint(position=(3, 6), direction=1)),
TrainrunWaypoint(scheduled_at=18, waypoint=Waypoint(position=(3, 7), direction=1)),
TrainrunWaypoint(scheduled_at=19, waypoint=Waypoint(position=(3, 8), direction=1)),
TrainrunWaypoint(scheduled_at=20, waypoint=Waypoint(position=(3, 8), direction=5))],
1: [TrainrunWaypoint(scheduled_at=0, waypoint=Waypoint(position=(3, 8), direction=3)),
TrainrunWaypoint(scheduled_at=3, waypoint=Waypoint(position=(3, 7), direction=3)),
TrainrunWaypoint(scheduled_at=5, waypoint=Waypoint(position=(3, 6), direction=3)),
TrainrunWaypoint(scheduled_at=7, waypoint=Waypoint(position=(3, 5), direction=3)),
TrainrunWaypoint(scheduled_at=9, waypoint=Waypoint(position=(3, 4), direction=3)),
TrainrunWaypoint(scheduled_at=11, waypoint=Waypoint(position=(3, 3), direction=3)),
TrainrunWaypoint(scheduled_at=13, waypoint=Waypoint(position=(2, 3), direction=0)),
TrainrunWaypoint(scheduled_at=15, waypoint=Waypoint(position=(1, 3), direction=0)),
TrainrunWaypoint(scheduled_at=17, waypoint=Waypoint(position=(0, 3), direction=0))]}
expected_action_plan = [[
# take action to enter the grid
ActionPlanElement(0, RailEnvActions.MOVE_FORWARD),
# take action to enter the cell properly
ActionPlanElement(1, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(2, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(3, RailEnvActions.STOP_MOVING),
ActionPlanElement(13, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(14, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(15, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(16, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(17, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(18, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(19, RailEnvActions.STOP_MOVING)
], [
ActionPlanElement(0, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(1, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(3, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(5, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(7, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(9, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(11, RailEnvActions.MOVE_RIGHT),
ActionPlanElement(13, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(15, RailEnvActions.MOVE_FORWARD),
ActionPlanElement(17, RailEnvActions.STOP_MOVING),
]]
deterministic_controller = ControllerFromTrainruns(env, chosen_path_dict)
deterministic_controller.print_action_plan()
ControllerFromTrainruns.assert_actions_plans_equal(expected_action_plan, deterministic_controller.action_plan)
if rendering:
renderer = RenderTool(env, gl="PILSVG",
agent_render_variant=AgentRenderVariant.AGENT_SHOWS_OPTIONS_AND_BOX,
show_debug=True,
clear_debug_text=True,
screen_height=1000,
screen_width=1000)
def render(*argv):
if rendering:
renderer.render_env(show=True, show_observations=False, show_predictions=False)
ControllerFromTrainrunsReplayer.replay_verify(deterministic_controller, env, call_back=render)
import numpy as np
from flatland.core.grid.rail_env_grid import RailEnvTransitions
from flatland.core.transition_map import GridTransitionMap
from flatland.envs.observations import TreeObsForRailEnv
from flatland.envs.predictions import ShortestPathPredictorForRailEnv
from flatland.envs.rail_env import RailEnv
from flatland.envs.rail_generators import rail_from_grid_transition_map
from flatland.envs.line_generators import sparse_line_generator
def test_walker():
# _ _ _
transitions = RailEnvTransitions()
cells = transitions.transition_list
dead_end_from_south = cells[7]
dead_end_from_west = transitions.rotate_transition(dead_end_from_south, 90)
dead_end_from_east = transitions.rotate_transition(dead_end_from_south, 270)
vertical_straight = cells[1]
horizontal_straight = transitions.rotate_transition(vertical_straight, 90)
rail_map = np.array(
[[dead_end_from_east] + [horizontal_straight] + [dead_end_from_west]], dtype=np.uint16)
rail = GridTransitionMap(width=rail_map.shape[1],
height=rail_map.shape[0], transitions=transitions)
rail.grid = rail_map
city_positions = [(0,2), (0, 1)]
train_stations = [
[( (0, 1), 0 ) ],
[( (0, 2), 0 ) ],
]
city_orientations = [1, 0]
agents_hints = {'num_agents': 1,
'city_positions': city_positions,
'train_stations': train_stations,
'city_orientations': city_orientations
}
optionals = {'agents_hints': agents_hints}
env = RailEnv(width=rail_map.shape[1],
height=rail_map.shape[0],
rail_generator=rail_from_grid_transition_map(rail, optionals),
line_generator=sparse_line_generator(),
number_of_agents=1,
obs_builder_object=TreeObsForRailEnv(max_depth=2,
predictor=ShortestPathPredictorForRailEnv(max_depth=10)),
)
env.reset()
# set initial position and direction for testing...
env.agents[0].position = (0, 1)
env.agents[0].direction = 1
env.agents[0].target = (0, 0)
# reset to set agents from agents_static
# env.reset(False, False)
env.distance_map._compute(env.agents, env.rail)
print(env.distance_map.get()[(0, *[0, 1], 1)])
assert env.distance_map.get()[(0, *[0, 1], 1)] == 3
print(env.distance_map.get()[(0, *[0, 2], 3)])
assert env.distance_map.get()[(0, *[0, 2], 1)] == 2
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
from flatland.core.env_observation_builder import GlobalObsForRailEnv
from flatland.core.transition_map import GridTransitionMap, Grid4Transitions
from flatland.envs.rail_env import RailEnv
from flatland.envs.generators import rail_from_GridTransitionMap_generator
"""Tests for `flatland` package."""
def test_global_obs():
# We instantiate a very simple rail network on a 7x10 grid:
# |
# |
# |
# _ _ _ /_\ _ _ _ _ _ _
# \ /
# |
# |
# |
cells = [int('0000000000000000', 2), # empty cell - Case 0
int('1000000000100000', 2), # Case 1 - straight
int('1001001000100000', 2), # Case 2 - simple switch
int('1000010000100001', 2), # Case 3 - diamond drossing
int('1001011000100001', 2), # Case 4 - single slip switch
int('1100110000110011', 2), # Case 5 - double slip switch
int('0101001000000010', 2), # Case 6 - symmetrical switch
int('0010000000000000', 2)] # Case 7 - dead end
transitions = Grid4Transitions([])
empty = cells[0]
dead_end_from_south = cells[7]
dead_end_from_west = transitions.rotate_transition(dead_end_from_south, 90)
dead_end_from_north = transitions.rotate_transition(dead_end_from_south, 180)
dead_end_from_east = transitions.rotate_transition(dead_end_from_south, 270)
vertical_straight = cells[1]
horizontal_straight = transitions.rotate_transition(vertical_straight, 90)
double_switch_south_horizontal_straight = horizontal_straight + cells[6]
double_switch_north_horizontal_straight = transitions.rotate_transition(
double_switch_south_horizontal_straight, 180)
rail_map = np.array(
[[empty] * 3 + [dead_end_from_south] + [empty] * 6] +
[[empty] * 3 + [vertical_straight] + [empty] * 6] * 2 +
[[dead_end_from_east] + [horizontal_straight] * 2 +
[double_switch_north_horizontal_straight] +
[horizontal_straight] * 2 + [double_switch_south_horizontal_straight] +
[horizontal_straight] * 2 + [dead_end_from_west]] +
[[empty] * 6 + [vertical_straight] + [empty] * 3] * 2 +
[[empty] * 6 + [dead_end_from_north] + [empty] * 3], dtype=np.uint16)
rail = GridTransitionMap(width=rail_map.shape[1],
height=rail_map.shape[0], transitions=transitions)
rail.grid = rail_map
env = RailEnv(width=rail_map.shape[1],
height=rail_map.shape[0],
rail_generator=rail_from_GridTransitionMap_generator(rail),
number_of_agents=1,
obs_builder_object=GlobalObsForRailEnv())
global_obs = env.reset()
# env_renderer = RenderTool(env)
# env_renderer.renderEnv(show=True)
# global_obs.reset()
assert(global_obs[0][0].shape == rail_map.shape + (16,))
rail_map_recons = np.zeros_like(rail_map)
for i in range(global_obs[0][0].shape[0]):
for j in range(global_obs[0][0].shape[1]):
rail_map_recons[i, j] = int(
''.join(global_obs[0][0][i, j].astype(int).astype(str)), 2)
assert(rail_map_recons.all() == rail_map.all())
# If this assertion is wrong, it means that the observation returned
# places the agent on an empty cell
assert(np.sum(rail_map * global_obs[0][1][0]) > 0)
def main():
test_global_obs()
if __name__ == "__main__":
main()
import numpy as np
import numpy as np
import os
from flatland.envs.malfunction_generators import malfunction_from_params, MalfunctionParameters, ParamMalfunctionGen
from flatland.envs.observations import GlobalObsForRailEnv
# First of all we import the Flatland rail environment
from flatland.envs.rail_env import RailEnv
from flatland.envs.rail_env import RailEnvActions
from flatland.envs.rail_generators import sparse_rail_generator
#from flatland.envs.sparse_rail_gen import SparseRailGen
from flatland.envs.line_generators import sparse_line_generator
def get_small_two_agent_env():
"""Generates a simple 2 city 2 train env returns it after reset"""
width = 30 # With of map
height = 15 # Height of map
nr_trains = 2 # Number of trains that have an assigned task in the env
cities_in_map = 2 # Number of cities where agents can start or end
seed = 42 # Random seed
grid_distribution_of_cities = False # Type of city distribution, if False cities are randomly placed
max_rails_between_cities = 2 # Max number of tracks allowed between cities. This is number of entry point to a city
max_rail_in_cities = 6 # Max number of parallel tracks within a city, representing a realistic trainstation
rail_generator = sparse_rail_generator(max_num_cities=cities_in_map,
seed=seed,
grid_mode=grid_distribution_of_cities,
max_rails_between_cities=max_rails_between_cities,
max_rail_pairs_in_city=max_rail_in_cities//2,
)
speed_ration_map = {1.: 0.25, # Fast passenger train
1. / 2.: 0.25, # Fast freight train
1. / 3.: 0.25, # Slow commuter train
1. / 4.: 0.25} # Slow freight train
line_generator = sparse_line_generator(speed_ration_map)
stochastic_data = MalfunctionParameters(malfunction_rate=1/10000, # Rate of malfunction occurence
min_duration=15, # Minimal duration of malfunction
max_duration=50 # Max duration of malfunction
)
observation_builder = GlobalObsForRailEnv()
env = RailEnv(width=width,
height=height,
rail_generator=rail_generator,
line_generator=line_generator,
number_of_agents=nr_trains,
obs_builder_object=observation_builder,
#malfunction_generator_and_process_data=malfunction_from_params(stochastic_data),
malfunction_generator=ParamMalfunctionGen(stochastic_data),
remove_agents_at_target=True,
random_seed=seed)
env.reset()
return env
\ No newline at end of file
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
from flatland.envs.rail_env import RailEnv
from flatland.envs.generators import rail_from_GridTransitionMap_generator
from flatland.core.transitions import Grid4Transitions
from flatland.core.transition_map import GridTransitionMap
from flatland.core.env_observation_builder import GlobalObsForRailEnv
from flatland.envs.agent_utils import EnvAgent
"""Tests for `flatland` package."""
def test_rail_environment_single_agent():
cells = [int('0000000000000000', 2), # empty cell - Case 0
int('1000000000100000', 2), # Case 1 - straight
int('1001001000100000', 2), # Case 2 - simple switch
int('1000010000100001', 2), # Case 3 - diamond drossing
int('1001011000100001', 2), # Case 4 - single slip switch
int('1100110000110011', 2), # Case 5 - double slip switch
int('0101001000000010', 2), # Case 6 - symmetrical switch
int('0010000000000000', 2)] # Case 7 - dead end
# We instantiate the following map on a 3x3 grid
# _ _
# / \/ \
# | | |
# \_/\_/
transitions = Grid4Transitions([])
vertical_line = cells[1]
south_symmetrical_switch = cells[6]
north_symmetrical_switch = transitions.rotate_transition(south_symmetrical_switch, 180)
# Simple turn not in the base transitions ?
south_east_turn = int('0100000000000010', 2)
south_west_turn = transitions.rotate_transition(south_east_turn, 90)
north_east_turn = transitions.rotate_transition(south_east_turn, 270)
north_west_turn = transitions.rotate_transition(south_east_turn, 180)
rail_map = np.array([[south_east_turn, south_symmetrical_switch,
south_west_turn],
[vertical_line, vertical_line, vertical_line],
[north_east_turn, north_symmetrical_switch,
north_west_turn]],
dtype=np.uint16)
rail = GridTransitionMap(width=3, height=3, transitions=transitions)
rail.grid = rail_map
rail_env = RailEnv(width=3,
height=3,
rail_generator=rail_from_GridTransitionMap_generator(rail),
number_of_agents=1,
obs_builder_object=GlobalObsForRailEnv())
for _ in range(200):
_ = rail_env.reset()
# We do not care about target for the moment
# rail_env.agents_target[0] = [-1, -1]
agent = rail_env.agents[0]
# rail_env.agents[0].target = [-1, -1]
agent.target = [-1, -1]
# Check that trains are always initialized at a consistent position
# or direction.
# They should always be able to go somewhere.
assert(transitions.get_transitions(
# rail_map[rail_env.agents_position[0]],
# rail_env.agents_direction[0]) != (0, 0, 0, 0))
rail_map[agent.position],
agent.direction) != (0, 0, 0, 0))
initial_pos = agent.position
valid_active_actions_done = 0
pos = initial_pos
while valid_active_actions_done < 6:
# We randomly select an action
action = np.random.randint(4)
_, _, _, _ = rail_env.step({0: action})
prev_pos = pos
pos = agent.position # rail_env.agents_position[0]
if prev_pos != pos:
valid_active_actions_done += 1
# After 6 movements on this railway network, the train should be back
# to its original height on the map.
assert(initial_pos[0] == agent.position[0])
# We check that the train always attains its target after some time
for _ in range(10):
_ = rail_env.reset()
done = False
while not done:
# We randomly select an action
action = np.random.randint(4)
_, _, dones, _ = rail_env.step({0: action})
done = dones['__all__']
def test_dead_end():
transitions = Grid4Transitions([])
straight_vertical = int('1000000000100000', 2) # Case 1 - straight
straight_horizontal = transitions.rotate_transition(straight_vertical,
90)
dead_end_from_south = int('0010000000000000', 2) # Case 7 - dead end
# We instantiate the following railway
# O->-- where > is the train and O the target. After 6 steps,
# the train should be done.
rail_map = np.array(
[[transitions.rotate_transition(dead_end_from_south, 270)] +
[straight_horizontal] * 3 +
[transitions.rotate_transition(dead_end_from_south, 90)]],
dtype=np.uint16)
rail = GridTransitionMap(width=rail_map.shape[1],
height=rail_map.shape[0],
transitions=transitions)
rail.grid = rail_map
rail_env = RailEnv(width=rail_map.shape[1],
height=rail_map.shape[0],
rail_generator=rail_from_GridTransitionMap_generator(rail),
number_of_agents=1,
obs_builder_object=GlobalObsForRailEnv())
def check_consistency(rail_env):
# We run step to check that trains do not move anymore
# after being done.
for i in range(7):
# prev_pos = rail_env.agents_position[0]
prev_pos = rail_env.agents[0].position
# The train cannot turn, so we check that when it tries,
# it stays where it is.
_ = rail_env.step({0: 1})
_ = rail_env.step({0: 3})
assert (rail_env.agents[0].position == prev_pos)
_, _, dones, _ = rail_env.step({0: 2})
if i < 5:
assert (not dones[0] and not dones['__all__'])
else:
assert (dones[0] and dones['__all__'])
# We try the configuration in the 4 directions:
rail_env.reset()
# rail_env.agents_target[0] = (0, 0)
# rail_env.agents_position[0] = (0, 2)
# rail_env.agents_direction[0] = 1
rail_env.agents = [EnvAgent(position=(0, 2), direction=1, target=(0, 0))]
check_consistency(rail_env)
rail_env.reset()
# rail_env.agents_target[0] = (0, 4)
# rail_env.agents_position[0] = (0, 2)
# rail_env.agents_direction[0] = 3
rail_env.agents = [EnvAgent(position=(0, 2), direction=3, target=(0, 4))]
check_consistency(rail_env)
# In the vertical configuration:
rail_map = np.array(
[[dead_end_from_south]] + [[straight_vertical]] * 3 +
[[transitions.rotate_transition(dead_end_from_south, 180)]],
dtype=np.uint16)
rail = GridTransitionMap(width=rail_map.shape[1],
height=rail_map.shape[0],
transitions=transitions)
rail.grid = rail_map
rail_env = RailEnv(width=rail_map.shape[1],
height=rail_map.shape[0],
rail_generator=rail_from_GridTransitionMap_generator(rail),
number_of_agents=1,
obs_builder_object=GlobalObsForRailEnv())
rail_env.reset()
# rail_env.agents_target[0] = (0, 0)
# rail_env.agents_position[0] = (2, 0)
# rail_env.agents_direction[0] = 2
rail_env.agents = [EnvAgent(position=(2, 0), direction=2, target=(0, 0))]
check_consistency(rail_env)
rail_env.reset()
# rail_env.agents_target[0] = (4, 0)
# rail_env.agents_position[0] = (2, 0)
# rail_env.agents_direction[0] = 0
rail_env.agents = [EnvAgent(position=(2, 0), direction=0, target=(4, 0))]
check_consistency(rail_env)
if __name__ == "__main__":
test_rail_environment_single_agent()
test_dead_end()
\ No newline at end of file
from flatland.evaluators.client import FlatlandRemoteClient
from flatland.core.env_observation_builder import DummyObservationBuilder
#from my_observation_builder import CustomObservationBuilder
import numpy as np
import time
from flatland.core.env import Environment
from flatland.core.env_observation_builder import ObservationBuilder
class CustomObservationBuilder(ObservationBuilder):
def __init__(self):
super(CustomObservationBuilder, self).__init__()
def set_env(self, env: Environment):
super().set_env(env)
# Note :
# The instantiations which depend on parameters of the Env object should be
# done here, as it is only here that the updated self.env instance is available
self.rail_obs = np.zeros((self.env.height, self.env.width))
def reset(self):
"""
Called internally on every env.reset() call,
to reset any observation specific variables that are being used
"""
self.rail_obs[:] = 0
for _x in range(self.env.width):
for _y in range(self.env.height):
# Get the transition map value at location _x, _y
transition_value = self.env.rail.get_full_transitions(_y, _x)
self.rail_obs[_y, _x] = transition_value
def get(self, handle: int = 0):
agent = self.env.agents[handle]
status = agent.status
position = agent.position
direction = agent.direction
initial_position = agent.initial_position
target = agent.target
return self.rail_obs, (status, position, direction, initial_position, target)
def my_controller(obs, number_of_agents):
_action = {}
for _idx in range(number_of_agents):
_action[_idx] = np.random.randint(0, 5)
return _action
def __disabled__test_random_timeouts():
remote_client = FlatlandRemoteClient(verbose=False)
my_observation_builder = CustomObservationBuilder()
evaluation_number = 0
n_evalations = 10
step_delay_rate = 0.001
step_delay = 6
reset_delay_rate = 0.2
reset_delay = 10
while evaluation_number < n_evalations:
evaluation_number += 1
# Switch to a new evaluation environemnt
#
# a remote_client.env_create is similar to instantiating a
# RailEnv and then doing a env.reset()
# hence it returns the first observation from the
# env.reset()
#
# You can also pass your custom observation_builder object
# to allow you to have as much control as you wish
# over the observation of your choice.
time_start = time.time()
observation, info = remote_client.env_create(
obs_builder_object=my_observation_builder
)
env_creation_time = time.time() - time_start
if not observation:
#
# If the remote_client returns False on a `env_create` call,
# then it basically means that your agent has already been
# evaluated on all the required evaluation environments,
# and hence its safe to break out of the main evaluation loop
break
print("Evaluation Number : {}".format(evaluation_number))
if np.random.uniform() < reset_delay_rate:
print(f"eval {evaluation_number} sleeping for {reset_delay} seconds")
time.sleep(reset_delay)
local_env = remote_client.env
number_of_agents = len(local_env.agents)
time_taken_by_controller = []
time_taken_per_step = []
steps = 0
while True:
time_start = time.time()
action = my_controller(observation, number_of_agents)
time_taken = time.time() - time_start
time_taken_by_controller.append(time_taken)
time_start = time.time()
try:
observation, all_rewards, done, info = remote_client.env_step(action)
except StopAsyncIteration as err:
print("timeout error ", err)
break
steps += 1
time_taken = time.time() - time_start
time_taken_per_step.append(time_taken)
if np.random.uniform() < step_delay_rate:
print(f"step {steps} sleeping for {step_delay} seconds")
time.sleep(step_delay)
if done['__all__']:
print("Reward : ", sum(list(all_rewards.values())))
break
np_time_taken_by_controller = np.array(time_taken_by_controller)
np_time_taken_per_step = np.array(time_taken_per_step)
print("="*100)
print("="*100)
print("Evaluation Number : ", evaluation_number)
print("Current Env Path : ", remote_client.current_env_path)
print("Env Creation Time : ", env_creation_time)
print("Number of Steps : ", steps)
print("Mean/Std of Time taken by Controller : ", np_time_taken_by_controller.mean(), np_time_taken_by_controller.std())
print("Mean/Std of Time per Step : ", np_time_taken_per_step.mean(), np_time_taken_per_step.std())
print("="*100)
print("Evaluation of all environments complete...")
########################################################################
# Submit your Results
#
# Please do not forget to include this call, as this triggers the
# final computation of the score statistics, video generation, etc
# and is necesaary to have your submission marked as successfully evaluated
########################################################################
print(remote_client.submit())
if __name__ == "__main__":
test_random_timeouts()
\ No newline at end of file
import numpy as np
from flatland.core.grid.rail_env_grid import RailEnvTransitions
from flatland.core.transition_map import GridTransitionMap
from flatland.envs.grid4_generators_utils import connect_rail_in_grid_map, connect_straight_line_in_grid_map, \
fix_inner_nodes
def test_build_railway_infrastructure():
rail_trans = RailEnvTransitions()
grid_map = GridTransitionMap(width=20, height=20, transitions=rail_trans)
grid_map.grid.fill(0)
# Make connection with dead-ends on both sides
start_point = (2, 2)
end_point = (8, 8)
connection_001 = connect_rail_in_grid_map(grid_map, start_point, end_point, rail_trans, flip_start_node_trans=True,
flip_end_node_trans=True, respect_transition_validity=True,
forbidden_cells=None)
connection_001_expected = [(2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (3, 8), (4, 8), (5, 8), (6, 8),
(7, 8), (8, 8)]
# Make connection with open ends on both sides
start_point = (1, 3)
end_point = (1, 7)
connection_002 = connect_rail_in_grid_map(grid_map, start_point, end_point, rail_trans, flip_start_node_trans=False,
flip_end_node_trans=False, respect_transition_validity=True,
forbidden_cells=None)
connection_002_expected = [(1, 3), (1, 4), (1, 5), (1, 6), (1, 7)]
# Make connection with open end at beginning and dead end on end
start_point = (6, 2)
end_point = (6, 5)
connection_003 = connect_rail_in_grid_map(grid_map, start_point, end_point, rail_trans, flip_start_node_trans=False,
flip_end_node_trans=True, respect_transition_validity=True,
forbidden_cells=None)
connection_003_expected = [(6, 2), (6, 3), (6, 4), (6, 5)]
# Make connection with dead end on start and opend end
start_point = (7, 5)
end_point = (8, 9)
connection_004 = connect_rail_in_grid_map(grid_map, start_point, end_point, rail_trans, flip_start_node_trans=True,
flip_end_node_trans=False, respect_transition_validity=True,
forbidden_cells=None)
connection_004_expected = [(7, 5), (7, 6), (7, 7), (7, 8), (7, 9), (8, 9)]
assert connection_001 == connection_001_expected, \
"actual={}, expected={}".format(connection_001, connection_001_expected)
assert connection_002 == connection_002_expected, \
"actual={}, expected={}".format(connection_002, connection_002_expected)
assert connection_003 == connection_003_expected, \
"actual={}, expected={}".format(connection_003, connection_003_expected)
assert connection_004 == connection_004_expected, \
"actual={}, expected={}".format(connection_004, connection_004_expected)
grid_map_grid_expected = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1025, 1025, 1025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 4, 1025, 1025, 1025, 1025, 1025, 4608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 32800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 32800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 32800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1025, 1025, 256, 0, 0, 32800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 4, 1025, 1025, 33825, 4608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
for i in range(len(grid_map_grid_expected)):
assert np.all(grid_map.grid[i] == grid_map_grid_expected[i])
def test_fix_inner_nodes():
rail_trans = RailEnvTransitions()
grid_map = GridTransitionMap(width=6, height=10, transitions=rail_trans)
grid_map.grid.fill(0)
start = (2, 2)
target = (8, 2)
parallel_start = (3, 3)
parallel_target = (7, 3)
parallel_start_1 = (4, 4)
parallel_target_1 = (6, 4)
inner_nodes = [start, target, parallel_start, parallel_target, parallel_start_1, parallel_target_1]
track_0 = connect_straight_line_in_grid_map(grid_map, start, target, rail_trans)
track_1 = connect_straight_line_in_grid_map(grid_map, parallel_start, parallel_target, rail_trans)
track_2 = connect_straight_line_in_grid_map(grid_map, parallel_start_1, parallel_target_1, rail_trans)
# Fix the ends of the inner node
# This is not a fix in transition type but rather makes the necessary connections to the parallel tracks
for node in inner_nodes:
fix_inner_nodes(grid_map, node, rail_trans)
def orienation(pos):
if pos[0] < grid_map.grid.shape[0] / 2:
return 2
else:
return 0
# Fix all the different transitions to legal elements
for c in range(grid_map.grid.shape[1]):
for r in range(grid_map.grid.shape[0]):
grid_map.fix_transitions((r, c), orienation((r, c)))
# Print for assertion tests
# print("assert grid_map.grid[{}] == {}".format((r,c),grid_map.grid[(r,c)]))
assert grid_map.grid[(1, 0)] == 0
assert grid_map.grid[(2, 0)] == 0
assert grid_map.grid[(3, 0)] == 0
assert grid_map.grid[(4, 0)] == 0
assert grid_map.grid[(5, 0)] == 0
assert grid_map.grid[(6, 0)] == 0
assert grid_map.grid[(7, 0)] == 0
assert grid_map.grid[(8, 0)] == 0
assert grid_map.grid[(9, 0)] == 0
assert grid_map.grid[(0, 1)] == 0
assert grid_map.grid[(1, 1)] == 0
assert grid_map.grid[(2, 1)] == 0
assert grid_map.grid[(3, 1)] == 0
assert grid_map.grid[(4, 1)] == 0
assert grid_map.grid[(5, 1)] == 0
assert grid_map.grid[(6, 1)] == 0
assert grid_map.grid[(7, 1)] == 0
assert grid_map.grid[(8, 1)] == 0
assert grid_map.grid[(9, 1)] == 0
assert grid_map.grid[(0, 2)] == 0
assert grid_map.grid[(1, 2)] == 0
assert grid_map.grid[(2, 2)] == 8192
assert grid_map.grid[(3, 2)] == 49186
assert grid_map.grid[(4, 2)] == 32800
assert grid_map.grid[(5, 2)] == 32800
assert grid_map.grid[(6, 2)] == 32800
assert grid_map.grid[(7, 2)] == 32872
assert grid_map.grid[(8, 2)] == 128
assert grid_map.grid[(9, 2)] == 0
assert grid_map.grid[(0, 3)] == 0
assert grid_map.grid[(1, 3)] == 0
assert grid_map.grid[(2, 3)] == 0
assert grid_map.grid[(3, 3)] == 4608
assert grid_map.grid[(4, 3)] == 49186
assert grid_map.grid[(5, 3)] == 32800
assert grid_map.grid[(6, 3)] == 32872
assert grid_map.grid[(7, 3)] == 2064
assert grid_map.grid[(8, 3)] == 0
assert grid_map.grid[(9, 3)] == 0
assert grid_map.grid[(0, 4)] == 0
assert grid_map.grid[(1, 4)] == 0
assert grid_map.grid[(2, 4)] == 0
assert grid_map.grid[(3, 4)] == 0
assert grid_map.grid[(4, 4)] == 4608
assert grid_map.grid[(5, 4)] == 32800
assert grid_map.grid[(6, 4)] == 2064
assert grid_map.grid[(7, 4)] == 0
assert grid_map.grid[(8, 4)] == 0
assert grid_map.grid[(9, 4)] == 0
assert grid_map.grid[(0, 5)] == 0
assert grid_map.grid[(1, 5)] == 0
assert grid_map.grid[(2, 5)] == 0
assert grid_map.grid[(3, 5)] == 0
assert grid_map.grid[(4, 5)] == 0
assert grid_map.grid[(5, 5)] == 0
assert grid_map.grid[(6, 5)] == 0
assert grid_map.grid[(7, 5)] == 0
assert grid_map.grid[(8, 5)] == 0
assert grid_map.grid[(9, 5)] == 0