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 2489 additions and 62 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:
## 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
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:90% !important; }</style>"))
```
%% Cell type:code id: tags:
``` python
import importlib_resources as ir
```
%% Cell type:code id: tags:
``` python
from flatland.envs.persistence import RailEnvPersister
from flatland.utils import jupyter_utils as ju
```
%% Cell type:code id: tags:
``` python
lsPackages = [ "env_data.railway"]
```
%% Cell type:code id: tags:
``` python
ltPackRes = []
for sPack in lsPackages:
for sExt in ["mpk", "pkl"]:
ltPackRes += [ (sPack, sRes) for sRes in ir.contents(sPack) if sRes.endswith(sExt) ]
ltPackRes
```
%% Cell type:code id: tags:
``` python
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()
```
%% 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
```
......@@ -4,14 +4,20 @@ wheel>=0.32.1
watchdog>=0.9.0
benchmarker>=4.0.1
coverage>=4.5.1
Sphinx>=1.8.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
pytest-xvfb>=1.2.0
PyVirtualDisplay==1.3.2
pytest-xvfb==2.0.0
git+https://github.com/who8mylunch/Jupyter_Canvas_Widget.git@bd151ae1509c50b5809944dd3294f58b7b069c86
m2r>=0.2.1
# contains all requirements to run the tests by running ```tox -e py36,py37```
tox>=3.5.2
twine>=1.12.1
pytest>=3.8.2
pytest>=3.8.2,<5
pytest-runner>=4.2
numpy>=1.16.4
Click>=7.0
crowdai-api>=0.1.21
numpy>=1.16.2
recordtype>=1.3
xarray>=0.11.3
matplotlib>=3.0.2
Pillow>=5.4.1
CairoSVG>=2.3.1
msgpack>=0.6.1
msgpack>=1.0.0,<2.0.0
msgpack-numpy>=0.4.4.0
svgutils>=0.3.1
screeninfo>=0.3.1
pyarrow>=0.13.0
pandas>=0.25.1
importlib-metadata>=0.17
importlib-resources>=1.0.1
importlib-resources>=1.0.1,<2
six>=1.12.0
timeout-decorator>=0.4.1
attrs
ushlex
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.2.0
current_version = 3.0.15
commit = True
tag = True
......@@ -22,4 +22,3 @@ test = pytest
[tool:pytest]
collect_ignore = ['setup.py']
......@@ -8,7 +8,7 @@ import sys
from setuptools import setup, find_packages
assert sys.version_info >= (3, 6)
with open('README.rst') as readme_file:
with open('README.md', 'r', encoding='utf8') as readme_file:
readme = readme_file.read()
......@@ -16,7 +16,7 @@ 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))
ret.append(os.path.join(dirpath, f))
return ret
......@@ -24,7 +24,7 @@ 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))
ret.append(os.path.join(dirpath, f))
return ret
......@@ -32,7 +32,7 @@ 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))
ret.append(os.path.join(dirpath, f))
return ret
......@@ -53,7 +53,7 @@ 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',
......@@ -62,11 +62,13 @@ 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,
long_description_content_type="text/markdown",
include_package_data=True,
keywords='flatland',
name='flatland-rl',
......@@ -78,6 +80,6 @@ setup(
test_suite='tests',
tests_require=test_requirements,
url='https://gitlab.aicrowd.com/flatland/flatland',
version='0.2.0',
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.grid4 import Grid4Transitions
from flatland.core.grid.rail_env_grid import RailEnvTransitions
from flatland.core.transition_map import GridTransitionMap
from flatland.envs.generators import rail_from_GridTransitionMap_generator
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():
# _ _ _
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([])
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)
......@@ -31,26 +25,39 @@ def test_walker():
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_GridTransitionMap_generator(rail),
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)),
)
# reset to initialize agents_static
env.reset()
# set initial position and direction for testing...
env.agents_static[0].position = (0, 1)
env.agents_static[0].direction = 1
env.agents_static[0].target = (0, 0)
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)
obs_builder: TreeObsForRailEnv = env.obs_builder
# env.reset(False, False)
env.distance_map._compute(env.agents, env.rail)
print(obs_builder.distance_map[(0, *[0, 1], 1)])
assert obs_builder.distance_map[(0, *[0, 1], 1)] == 3
print(obs_builder.distance_map[(0, *[0, 2], 3)])
assert obs_builder.distance_map[(0, *[0, 2], 1)] == 2
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
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
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
import numpy as np
from flatland.core.grid.grid_utils import Vec2dOperations as Vec2d
def test_vec2d_is_equal():
node_a = (1, 2)
node_b = (2, 4)
node_c = (1, 2)
res_1 = Vec2d.is_equal(node_a, node_b)
res_2 = Vec2d.is_equal(node_a, node_c)
assert not res_1
assert res_2
def test_vec2d_subtract():
node_a = (1, 2)
node_b = (2, 4)
res_1 = Vec2d.subtract(node_a, node_b)
res_2 = Vec2d.subtract(node_b, node_a)
assert res_1 != res_2
assert res_1 == (-1, -2)
assert res_2 == (1, 2)
def test_vec2d_add():
node_a = (1, 2)
node_b = (2, 3)
res_1 = Vec2d.add(node_a, node_b)
res_2 = Vec2d.add(node_b, node_a)
assert res_1 == res_2
assert res_1 == (3, 5)
def test_vec2d_make_orthogonal():
node_a = (1, 2)
res_1 = Vec2d.make_orthogonal(node_a)
assert res_1 == (2, -1)
def test_vec2d_euclidean_distance():
node_a = (3, -7)
node_0 = (0, 0)
assert Vec2d.get_euclidean_distance(node_a, node_0) == Vec2d.get_norm(node_a)
def test_vec2d_manhattan_distance():
node_a = (3, -7)
node_0 = (0, 0)
assert Vec2d.get_manhattan_distance(node_a, node_0) == 3 + 7
def test_vec2d_chebyshev_distance():
node_a = (3, -7)
node_0 = (0, 0)
assert Vec2d.get_chebyshev_distance(node_a, node_0) == 7
node_b = (-3, 7)
node_0 = (0, 0)
assert Vec2d.get_chebyshev_distance(node_b, node_0) == 7
node_c = (3, 7)
node_0 = (0, 0)
assert Vec2d.get_chebyshev_distance(node_c, node_0) == 7
def test_vec2d_norm():
node_a = (1, 2)
node_b = (1, -2)
res_1 = Vec2d.get_norm(node_a)
res_2 = Vec2d.get_norm(node_b)
assert np.sqrt(1 * 1 + 2 * 2) == res_1
assert np.sqrt(1 * 1 + (-2) * (-2)) == res_2
def test_vec2d_normalize():
node_a = (1, 2)
node_b = (1, -2)
res_1 = Vec2d.normalize(node_a)
res_2 = Vec2d.normalize(node_b)
assert np.isclose(1.0, Vec2d.get_norm(res_1))
assert np.isclose(1.0, Vec2d.get_norm(res_2))
def test_vec2d_scale():
node_a = (1, 2)
node_b = (1, -2)
res_1 = Vec2d.scale(node_a, 2)
res_2 = Vec2d.scale(node_b, -2.5)
assert res_1 == (2, 4)
assert res_2 == (-2.5, 5)
def test_vec2d_round():
node_a = (-1.95, -2.2)
node_b = (1.95, 2.2)
res_1 = Vec2d.round(node_a)
res_2 = Vec2d.round(node_b)
assert res_1 == (-2, -2)
assert res_2 == (2, 2)
def test_vec2d_ceil():
node_a = (-1.95, -2.2)
node_b = (1.95, 2.2)
res_1 = Vec2d.ceil(node_a)
res_2 = Vec2d.ceil(node_b)
assert res_1 == (-1, -2)
assert res_2 == (2, 3)
def test_vec2d_floor():
node_a = (-1.95, -2.2)
node_b = (1.95, 2.2)
res_1 = Vec2d.floor(node_a)
res_2 = Vec2d.floor(node_b)
assert res_1 == (-2, -3)
assert res_2 == (1, 2)
def test_vec2d_bound():
node_a = (-1.95, -2.2)
node_b = (1.95, 2.2)
res_1 = Vec2d.bound(node_a, -1, 0)
res_2 = Vec2d.bound(node_b, 2, 2.2)
assert res_1 == (-1, -1)
assert res_2 == (2, 2.2)
def test_vec2d_rotate():
node_a = (-1.95, -2.2)
res_1 = Vec2d.rotate(node_a, -90.0)
res_2 = Vec2d.rotate(node_a, 0.0)
res_3 = Vec2d.rotate(node_a, 90.0)
res_4 = Vec2d.rotate(node_a, 180.0)
res_5 = Vec2d.rotate(node_a, 270.0)
res_6 = Vec2d.rotate(node_a, 30.0)
res_1 = (Vec2d.get_norm(Vec2d.subtract(res_1, (-2.2, 1.95))))
res_2 = (Vec2d.get_norm(Vec2d.subtract(res_2, (-1.95, -2.2))))
res_3 = (Vec2d.get_norm(Vec2d.subtract(res_3, (2.2, -1.95))))
res_4 = (Vec2d.get_norm(Vec2d.subtract(res_4, (1.95, 2.2))))
res_5 = (Vec2d.get_norm(Vec2d.subtract(res_5, (-2.2, 1.95))))
res_6 = (Vec2d.get_norm(Vec2d.subtract(res_6, (-0.5887495373796556, -2.880255888325765))))
assert np.isclose(0, res_1)
assert np.isclose(0, res_2)
assert np.isclose(0, res_3)
assert np.isclose(0, res_4)
assert np.isclose(0, res_5)
assert np.isclose(0, res_6)
from flatland.core.grid.grid4 import Grid4Transitions, Grid4TransitionsEnum
from flatland.core.grid.grid8 import Grid8Transitions, Grid8TransitionsEnum
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
from flatland.utils.rendertools import RenderTool
from flatland.utils.simple_rail import make_simple_rail, make_simple_rail_unconnected
def test_grid4_get_transitions():
......@@ -43,4 +51,130 @@ def test_grid8_set_transitions():
grid8_map.set_transition((0, 0, Grid8TransitionsEnum.NORTH), Grid8TransitionsEnum.NORTH, 0)
assert grid8_map.get_transitions(0, 0, Grid8TransitionsEnum.NORTH) == (0, 0, 0, 0, 0, 0, 0, 0)
# TODO GridTransitionMap
def check_path(env, rail, position, direction, target, expected, rendering=False):
agent = env.agents[0]
agent.position = position # south dead-end
agent.direction = direction # north
agent.target = target # east dead-end
agent.moving = True
if rendering:
renderer = RenderTool(env, gl="PILSVG")
renderer.render_env(show=True, show_observations=False)
input("Continue?")
assert rail.check_path_exists(agent.position, agent.direction, agent.target) == expected
def test_path_exists(rendering=False):
rail, rail_map, optiionals = make_simple_rail()
env = RailEnv(width=rail_map.shape[1],
height=rail_map.shape[0],
rail_generator=rail_from_grid_transition_map(rail, optiionals),
line_generator=sparse_line_generator(),
number_of_agents=1,
obs_builder_object=TreeObsForRailEnv(max_depth=2, predictor=ShortestPathPredictorForRailEnv()),
)
env.reset()
check_path(
env,
rail,
(5, 6), # north of south dead-end
0, # north
(3, 9), # east dead-end
True
)
check_path(
env,
rail,
(6, 6), # south dead-end
2, # south
(3, 9), # east dead-end
True
)
check_path(
env,
rail,
(3, 0), # east dead-end
3, # west
(0, 3), # north dead-end
True
)
check_path(
env,
rail,
(5, 6), # east dead-end
0, # west
(1, 3), # north dead-end
True)
check_path(
env,
rail,
(1, 3), # east dead-end
2, # south
(3, 3), # north dead-end
True
)
check_path(
env,
rail,
(1, 3), # east dead-end
0, # north
(3, 3), # north dead-end
True
)
def test_path_not_exists(rendering=False):
rail, rail_map, optionals = make_simple_rail_unconnected()
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()),
)
env.reset()
check_path(
env,
rail,
(5, 6), # south dead-end
0, # north
(0, 3), # north dead-end
False
)
if rendering:
renderer = RenderTool(env, gl="PILSVG")
renderer.render_env(show=True, show_observations=False)
input("Continue?")
def test_get_entry_directions():
transitions = RailEnvTransitions()
cells = transitions.transition_list
vertical_line = cells[1]
south_symmetrical_switch = cells[6]
north_symmetrical_switch = transitions.rotate_transition(south_symmetrical_switch, 180)
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)
def _assert(transition, expected):
actual = Grid4Transitions.get_entry_directions(transition)
assert actual == expected, "Found {}, expected {}.".format(actual, expected)
_assert(south_east_turn, [True, False, False, True])
_assert(south_west_turn, [True, True, False, False])
_assert(north_east_turn, [False, False, True, True])
_assert(north_west_turn, [False, True, True, False])
_assert(vertical_line, [True, False, True, False])
_assert(south_symmetrical_switch, [True, True, False, True])
_assert(north_symmetrical_switch, [False, True, True, True])
......@@ -2,12 +2,10 @@
# -*- coding: utf-8 -*-
"""Tests for `flatland` package."""
import numpy as np
from flatland.core.grid.grid4 import Grid4Transitions
from flatland.core.grid.grid8 import Grid8Transitions
from flatland.core.grid.rail_env_grid import RailEnvTransitions
from flatland.core.grid.grid4_utils import validate_new_transition
from flatland.core.transition_map import GridTransitionMap
# remove whitespace in string; keep whitespace below for easier reading
......@@ -117,35 +115,35 @@ def test_is_valid_railenv_transitions():
def test_adding_new_valid_transition():
rail_trans = RailEnvTransitions()
rail_array = np.zeros(shape=(15, 15), dtype=np.uint16)
grid_map = GridTransitionMap(width=15, height=15, transitions=rail_trans)
# adding straight
assert (validate_new_transition(rail_trans, rail_array, (4, 5), (5, 5), (6, 5), (10, 10)) is True)
assert (grid_map.validate_new_transition((4, 5), (5, 5), (6, 5), (10, 10)) is True)
# adding valid right turn
assert (validate_new_transition(rail_trans, rail_array, (5, 4), (5, 5), (5, 6), (10, 10)) is True)
assert (grid_map.validate_new_transition((5, 4), (5, 5), (5, 6), (10, 10)) is True)
# adding valid left turn
assert (validate_new_transition(rail_trans, rail_array, (5, 6), (5, 5), (5, 6), (10, 10)) is True)
assert (grid_map.validate_new_transition((5, 6), (5, 5), (5, 6), (10, 10)) is True)
# adding invalid turn
rail_array[(5, 5)] = rail_trans.transitions[2]
assert (validate_new_transition(rail_trans, rail_array, (4, 5), (5, 5), (5, 6), (10, 10)) is False)
grid_map.grid[(5, 5)] = rail_trans.transitions[2]
assert (grid_map.validate_new_transition((4, 5), (5, 5), (5, 6), (10, 10)) is False)
# should create #4 -> valid
rail_array[(5, 5)] = rail_trans.transitions[3]
assert (validate_new_transition(rail_trans, rail_array, (4, 5), (5, 5), (5, 6), (10, 10)) is True)
grid_map.grid[(5, 5)] = rail_trans.transitions[3]
assert (grid_map.validate_new_transition((4, 5), (5, 5), (5, 6), (10, 10)) is True)
# adding invalid turn
rail_array[(5, 5)] = rail_trans.transitions[7]
assert (validate_new_transition(rail_trans, rail_array, (4, 5), (5, 5), (5, 6), (10, 10)) is False)
grid_map.grid[(5, 5)] = rail_trans.transitions[7]
assert (grid_map.validate_new_transition((4, 5), (5, 5), (5, 6), (10, 10)) is False)
# test path start condition
rail_array[(5, 5)] = rail_trans.transitions[0]
assert (validate_new_transition(rail_trans, rail_array, None, (5, 5), (5, 6), (10, 10)) is True)
grid_map.grid[(5, 5)] = rail_trans.transitions[0]
assert (grid_map.validate_new_transition(None, (5, 5), (5, 6), (10, 10)) is True)
# test path end condition
rail_array[(5, 5)] = rail_trans.transitions[0]
assert (validate_new_transition(rail_trans, rail_array, (5, 4), (5, 5), (6, 5), (6, 5)) is True)
grid_map.grid[(5, 5)] = rail_trans.transitions[0]
assert (grid_map.validate_new_transition((5, 4), (5, 5), (6, 5), (6, 5)) is True)
def test_valid_railenv_transitions():
......@@ -227,7 +225,7 @@ def test_rail_env_has_deadend():
transitions_all = ret.transitions_all
for t in transitions_all:
expected_has_deadend = t in deadends
actual_had_deadend = ret.has_deadend(t)
actual_had_deadend = Grid4Transitions.has_deadend(t)
assert actual_had_deadend == expected_has_deadend, \
"{} should be deadend = {}, actual = {}".format(t, )
......