diff --git a/.gitignore b/.gitignore index 2f1f81d1ba05de2544aeb53d61d2a222b59de31f..ce15e015aebdfab2e4b8a07f3633104ed3d2107b 100644 --- a/.gitignore +++ b/.gitignore @@ -119,3 +119,5 @@ test_save.dat .visualizations playground/ +**/tmp +**/TEMP \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7cd2116730ffc6dd5746d4596a9434e68e35f871..a31f70c849627749a548de123429766e2e7cc638 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,6 +10,7 @@ image: themattrix/tox ## - AWS_SECRET_ACCESS_KEY stages: + - build_wheel - tests - integration_testing - profiling @@ -149,4 +150,18 @@ test_conda_setup: script: - xvfb-run bash getting_started/getting_started.sh - +build_wheel: + image: "python:3.7-slim" + stage: build_wheel + before_script: + - apt update + - apt install -y make + - pip install -r requirements_dev.txt + script: + - make dist + - export WHEEL_NAME="$( find dist -name 'flatland_rl*.whl' )" + - mv "${WHEEL_NAME}" "${WHEEL_NAME/-py2.py3-/-py3-}" + artifacts: + paths: + - dist/flatland_rl*.whl + expire_in: 2 mos diff --git a/README.md b/README.md index 1eb84fe4036b6c8ec17eb141f4fac1ea7b74e055..99afdc866490cf1c495873a2cbda12993968f174 100644 --- a/README.md +++ b/README.md @@ -5,20 +5,22 @@ <p style="text-align:center"> <img alt="repository" src="https://gitlab.aicrowd.com/flatland/flatland/badges/master/pipeline.svg"> -<img alt="discord" src="https://gitlab.aicrowd.com/flatland/flatland/badges/master/coverage.svg"> +<img alt="coverage" src="https://gitlab.aicrowd.com/flatland/flatland/badges/master/coverage.svg"> </p> Flatland is a open-source toolkit for developing and comparing Multi Agent Reinforcement Learning algorithms in little (or ridiculously large!) gridworlds. [The official documentation](http://flatland.aicrowd.com/) contains full details about the environment and problem statement -Flatland is tested with Python 3.6 and 3.7 on modern versions of macOS, Linux and Windows. You may encounter problems with graphical rendering if you use WSL. Your [contribution is welcome](https://flatland.aicrowd.com/misc/contributing.html) if you can help with this! +Flatland is tested with Python 3.6, 3.7 and 3.8 on modern versions of macOS, Linux and Windows. You may encounter problems with graphical rendering if you use WSL. Your [contribution is welcome](https://flatland.aicrowd.com/misc/contributing.html) if you can help with this! 🆠Challenges --- This library was developed specifically for the AIcrowd [Flatland challenges](http://flatland.aicrowd.com/research/top-challenge-solutions.html) in which we strongly encourage you to take part in! +- [Flatland 3 Challenge](https://www.aicrowd.com/challenges/flatland-3) - ONGOING! +- [AMLD 2021 Challenge](https://www.aicrowd.com/challenges/flatland) - [NeurIPS 2020 Challenge](https://www.aicrowd.com/challenges/neurips-2020-flatland-challenge/) - [2019 Challenge](https://www.aicrowd.com/challenges/flatland-challenge) @@ -30,7 +32,7 @@ This library was developed specifically for the AIcrowd [Flatland challenges](ht Install [Anaconda](https://www.anaconda.com/distribution/) and create a new conda environment: ```console -$ conda create python=3.6 --name flatland-rl +$ conda create python=3.7 --name flatland-rl $ conda activate flatland-rl ``` @@ -57,7 +59,7 @@ $ git clone git@gitlab.aicrowd.com:flatland/flatland.git Once you have a copy of the source, install it with: ```console -$ python setup.py install +$ pip install -e . ``` ### Test installation @@ -77,7 +79,7 @@ python setup.py test 👥 Credits --- -This library was developed by [SBB](https://www.sbb.ch/en/), [Deutsche Bahn](https://www.deutschebahn.com/), [AIcrowd](https://www.aicrowd.com/) and [numerous contributors](http://flatland.aicrowd.com/misc/credits.html) and AIcrowd research fellows from the AIcrowd community. +This library was developed by [SBB](https://www.sbb.ch/en/), [Deutsche Bahn](https://www.deutschebahn.com/), [SNCF](https://www.sncf.com/en), [AIcrowd](https://www.aicrowd.com/) and [numerous contributors](http://flatland.aicrowd.com/misc/credits.html) and AIcrowd research fellows from the AIcrowd community. ➕ Contributions --- @@ -93,6 +95,7 @@ Please follow the [Contribution Guidelines](https://flatland.aicrowd.com/misc/co 🔗 Partners --- -<a href="https://sbb.ch" target="_blank" style="margin-right:25px"><img src="https://i.imgur.com/OSCXtde.png" alt="SBB" width="200"/></a> -<a href="https://www.deutschebahn.com/" target="_blank" style="margin-right:25px"><img src="https://i.imgur.com/pjTki15.png" alt="DB" width="200"/></a> -<a href="https://www.aicrowd.com" target="_blank"><img src="https://avatars1.githubusercontent.com/u/44522764?s=200&v=4" alt="AICROWD" width="200"/></a> +<a href="https://sbb.ch" target="_blank" style="margin-right:30px"><img src="https://annpr2020.ch/wp-content/uploads/2020/06/SBB.png" alt="SBB" width="140"/></a> +<a href="https://www.deutschebahn.com/" target="_blank" style="margin-right:30px"><img src="https://i.imgur.com/pjTki15.png" alt="DB" width="140"/></a> +<a href="https://www.sncf.com/en" target="_blank" style="margin-right:30px"><img src="https://iconape.com/wp-content/png_logo_vector/logo-sncf.png" alt="SNCF" width="140"/></a> +<a href="https://www.aicrowd.com" target="_blank"><img src="https://i.imgur.com/kBZQGI9.png" alt="AIcrowd" width="140"/></a> diff --git a/flatland/__init__.py b/flatland/__init__.py index 9444a28625957f4089ff257e902e348ed74afa8c..9d1f152b15db626553dc0dbb8512874f6b49b797 100644 --- a/flatland/__init__.py +++ b/flatland/__init__.py @@ -4,4 +4,4 @@ __author__ = """S.P. Mohanty""" __email__ = 'mohanty@aicrowd.com' -__version__ = '2.2.2' +__version__ = '3.0.0rc1' diff --git a/flatland/cli.py b/flatland/cli.py index 6dfc6c7de1a93afedf83e564d5962b588632b164..4692f421294a80cf28a479d9eca84c188fe172ba 100644 --- a/flatland/cli.py +++ b/flatland/cli.py @@ -9,8 +9,8 @@ import numpy as np import redis from flatland.envs.rail_env import RailEnv -from flatland.envs.rail_generators import complex_rail_generator -from flatland.envs.line_generators import complex_line_generator +from flatland.envs.rail_generators import sparse_rail_generator +from flatland.envs.line_generators import sparse_line_generator from flatland.evaluators.service import FlatlandRemoteEvaluationService from flatland.utils.rendertools import RenderTool @@ -18,35 +18,42 @@ from flatland.utils.rendertools import RenderTool @click.command() def demo(args=None): """Demo script to check installation""" - env = RailEnv(width=15, height=15, rail_generator=complex_rail_generator( - nr_start_goal=10, - nr_extra=1, - min_dist=8, - max_dist=99999), line_generator=complex_line_generator(), number_of_agents=5) + env = RailEnv( + width=30, + height=30, + rail_generator=sparse_rail_generator( + max_num_cities=3, + grid_mode=False, + max_rails_between_cities=4, + max_rail_pairs_in_city=2, + seed=0 + ), + line_generator=sparse_line_generator(), + number_of_agents=5) env._max_episode_steps = int(15 * (env.width + env.height)) env_renderer = RenderTool(env) - while True: - obs, info = env.reset() - _done = False - # Run a single episode here - step = 0 - while not _done: - # Compute Action - _action = {} - for _idx, _ in enumerate(env.agents): - _action[_idx] = np.random.randint(0, 5) - obs, all_rewards, done, _ = env.step(_action) - _done = done['__all__'] - step += 1 - env_renderer.render_env( - show=True, - frames=False, - show_observations=False, - show_predictions=False - ) - time.sleep(0.3) + obs, info = env.reset() + _done = False + # Run a single episode here + step = 0 + while not _done: + # Compute Action + _action = {} + for _idx, _ in enumerate(env.agents): + _action[_idx] = np.random.randint(0, 5) + obs, all_rewards, done, _ = env.step(_action) + _done = done['__all__'] + step += 1 + env_renderer.render_env( + show=True, + frames=False, + show_observations=False, + show_predictions=False + ) + time.sleep(0.1) + return 0 diff --git a/flatland/envs/persistence.py b/flatland/envs/persistence.py index 41f352e70017f1f37bb66abaa911d25725618836..188ac7c2f1ea2e0c9ea9f637670f154bb54e2518 100644 --- a/flatland/envs/persistence.py +++ b/flatland/envs/persistence.py @@ -310,4 +310,4 @@ class RailEnvPersister(object): self.height, self.width = self.rail.grid.shape self.rail.height = self.height self.rail.width = self.width - self.dones = dict.fromkeys(list(range(self.get_num_agents())) + ["__all__"], False) \ No newline at end of file + self.dones = dict.fromkeys(list(range(self.get_num_agents())) + ["__all__"], False) diff --git a/flatland/envs/rail_env.py b/flatland/envs/rail_env.py index 5021e4356801e2e77bc382a7500e1cf6ad5ac381..69c6cd2f6e31436fcf70d49697d0afc7a7328a6b 100644 --- a/flatland/envs/rail_env.py +++ b/flatland/envs/rail_env.py @@ -15,7 +15,7 @@ from flatland.core.grid.grid4 import Grid4TransitionsEnum, Grid4Transitions from flatland.core.grid.grid4_utils import get_new_position from flatland.core.grid.grid_utils import IntVector2D from flatland.core.transition_map import GridTransitionMap -from flatland.envs.agent_utils import EnvAgent, RailAgentStatus +from flatland.envs.agent_utils import Agent, EnvAgent, RailAgentStatus from flatland.envs.distance_map import DistanceMap from flatland.envs.rail_env_action import RailEnvActions @@ -477,6 +477,34 @@ class RailEnv(Environment): return + def _handle_end_reward(self, agent: EnvAgent) -> int: + ''' + Handles end-of-episode reward for a particular agent. + + Parameters + ---------- + agent : EnvAgent + ''' + reward = None + # agent done? (arrival_time is not None) + if agent.status == RailAgentStatus.DONE or agent.status == RailAgentStatus.DONE_REMOVED: + # if agent arrived earlier or on time = 0 + # if agent arrived later = -ve reward based on how late + reward = min(agent.latest_arrival - agent.arrival_time, 0) + + # Agents not done (arrival_time is None) + else: + # CANCELLED check (never departed) + if (agent.status == RailAgentStatus.READY_TO_DEPART): + reward = -1 * self.cancellation_factor * \ + (agent.get_travel_time_on_shortest_path(self.distance_map) + self.cancellation_time_buffer) + + # Departed but never reached + if (agent.status == RailAgentStatus.ACTIVE): + reward = agent.get_current_delay(self._elapsed_steps, self.distance_map) + + return reward + def step(self, action_dict_: Dict[int, RailEnvActions]): """ Updates rewards for the agents at a step. @@ -565,27 +593,8 @@ class RailEnv(Environment): for i_agent, agent in enumerate(self.agents): - # agent done? (arrival_time is not None) - if agent.status == RailAgentStatus.DONE or agent.status == RailAgentStatus.DONE_REMOVED: - - # if agent arrived earlier or on time = 0 - # if agent arrived later = -ve reward based on how late - reward = min(agent.latest_arrival - agent.arrival_time, 0) - self.rewards_dict[i_agent] += reward - - # Agents not done (arrival_time is None) - else: - - # CANCELLED check (never departed) - if (agent.status == RailAgentStatus.READY_TO_DEPART): - reward = -1 * self.cancellation_factor * \ - (agent.get_travel_time_on_shortest_path(self.distance_map) + 0) # 0 replaced with buffer - self.rewards_dict[i_agent] += reward - - # Departed but never reached - if (agent.status == RailAgentStatus.ACTIVE): - reward = agent.get_current_delay(self._elapsed_steps, self.distance_map) - self.rewards_dict[i_agent] += reward + reward = self._handle_end_reward(agent) + self.rewards_dict[i_agent] += reward self.dones[i_agent] = True diff --git a/flatland/envs/rail_generators.py b/flatland/envs/rail_generators.py index 08d2df07431fc8116c2713417a76a963a6e20489..90dcfb3612b7faaff7a3b277bae5efd780fba3e6 100644 --- a/flatland/envs/rail_generators.py +++ b/flatland/envs/rail_generators.py @@ -162,7 +162,7 @@ def sparse_rail_generator(*args, **kwargs): class SparseRailGen(RailGen): - def __init__(self, max_num_cities: int = 5, grid_mode: bool = False, max_rails_between_cities: int = 4, + def __init__(self, max_num_cities: int = 2, grid_mode: bool = False, max_rails_between_cities: int = 2, max_rail_pairs_in_city: int = 2, seed=0) -> RailGenerator: """ Generates railway networks with cities and inner city rails diff --git a/setup.cfg b/setup.cfg index cf0c6cc0825f60a55a3e7cce69295103fe5f40cb..555fa1badb5d1c5a9001fdd51c8ca4e187bbb91d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 2.2.2 +current_version = 3.0.0rc1 commit = True tag = True diff --git a/setup.py b/setup.py index 951597139909083748ad36810573ab0b2f3b47ed..22044d6c8b19938e9c7a9dd9aa817db83bb8b0cf 100644 --- a/setup.py +++ b/setup.py @@ -80,6 +80,6 @@ setup( test_suite='tests', tests_require=test_requirements, url='https://gitlab.aicrowd.com/flatland/flatland', - version='3.0.0', + version='3.0.0rc1', zip_safe=False, ) diff --git a/tests/test_flaltland_rail_agent_status.py b/tests/test_flatland_rail_agent_status.py similarity index 100% rename from tests/test_flaltland_rail_agent_status.py rename to tests/test_flatland_rail_agent_status.py