Commit d0d61948 authored by nimishsantosh107's avatar nimishsantosh107
Browse files

schedule constraints met, circular import fixed

parent d9d19b88
......@@ -7,7 +7,7 @@ import numpy as np
from flatland.core.env_prediction_builder import PredictionBuilder
from flatland.envs.agent_utils import RailAgentStatus
from flatland.envs.distance_map import DistanceMap
from flatland.envs.rail_env import RailEnvActions
from flatland.envs.rail_env_action import RailEnvActions
from flatland.envs.rail_env_shortest_paths import get_shortest_paths
from flatland.utils.ordered_set import OrderedSet
......
......@@ -17,6 +17,7 @@ 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.distance_map import DistanceMap
from flatland.envs.rail_env_action import RailEnvActions
# Need to use circular imports for persistence.
from flatland.envs import malfunction_generators as mal_gen
......@@ -67,28 +68,6 @@ def fast_count_nonzero(possible_transitions: (int, int, int, int)):
return possible_transitions[0] + possible_transitions[1] + possible_transitions[2] + possible_transitions[3]
class RailEnvActions(IntEnum):
DO_NOTHING = 0 # implies change of direction in a dead-end!
MOVE_LEFT = 1
MOVE_FORWARD = 2
MOVE_RIGHT = 3
STOP_MOVING = 4
@staticmethod
def to_char(a: int):
return {
0: 'B',
1: 'L',
2: 'F',
3: 'R',
4: 'S',
}[a]
RailEnvGridPos = NamedTuple('RailEnvGridPos', [('r', int), ('c', int)])
RailEnvNextAction = NamedTuple('RailEnvNextAction', [('action', RailEnvActions), ('next_position', RailEnvGridPos),
('next_direction', Grid4TransitionsEnum)])
class RailEnv(Environment):
"""
......@@ -247,7 +226,8 @@ class RailEnv(Environment):
self.dev_pred_dict = {}
self.agents: List[EnvAgent] = []
self.number_of_agents = number_of_agents
# NEW : SCHED CONST (Even number of trains A>B, B>A)
self.number_of_agents = number_of_agents if ((number_of_agents % 2) == 0 ) else number_of_agents + 1
self.num_resets = 0
self.distance_map = DistanceMap(self.agents, self.height, self.width)
......
from enum import IntEnum
from typing import NamedTuple
from flatland.core.grid.grid4 import Grid4TransitionsEnum
class RailEnvActions(IntEnum):
DO_NOTHING = 0 # implies change of direction in a dead-end!
MOVE_LEFT = 1
MOVE_FORWARD = 2
MOVE_RIGHT = 3
STOP_MOVING = 4
@staticmethod
def to_char(a: int):
return {
0: 'B',
1: 'L',
2: 'F',
3: 'R',
4: 'S',
}[a]
RailEnvGridPos = NamedTuple('RailEnvGridPos', [('r', int), ('c', int)])
RailEnvNextAction = NamedTuple('RailEnvNextAction', [('action', RailEnvActions), ('next_position', RailEnvGridPos),
('next_direction', Grid4TransitionsEnum)])
......@@ -9,7 +9,7 @@ from flatland.core.grid.grid4_utils import get_new_position
from flatland.core.transition_map import GridTransitionMap
from flatland.envs.agent_utils import RailAgentStatus
from flatland.envs.distance_map import DistanceMap
from flatland.envs.rail_env import RailEnvNextAction, RailEnvActions, RailEnv
from flatland.envs.rail_env_action import RailEnvActions, RailEnvNextAction
from flatland.envs.rail_trainrun_data_structures import Waypoint
from flatland.utils.ordered_set import OrderedSet
......@@ -274,7 +274,7 @@ def get_shortest_paths(distance_map: DistanceMap, max_depth: Optional[int] = Non
return shortest_paths
def get_k_shortest_paths(env: RailEnv,
def get_k_shortest_paths(env,
source_position: Tuple[int, int],
source_direction: int,
target_position=Tuple[int, int],
......
......@@ -608,7 +608,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,
max_rails_in_city: int = 4, seed=0) -> RailGenerator:
max_rail_pairs_in_city: int = 2, seed=0) -> RailGenerator:
"""
Generates railway networks with cities and inner city rails
......@@ -621,7 +621,7 @@ class SparseRailGen(RailGen):
max_rails_between_cities: int
Max number of rails connecting to a city. This is only the number of connection points at city boarder.
Number of tracks drawn inbetween cities can still vary
max_rails_in_city: int
max_rail_pairs_in_city: int
Number of parallel tracks in the city. This represents the number of tracks in the trainstations
seed: int
Initiate the seed
......@@ -633,7 +633,7 @@ class SparseRailGen(RailGen):
self.max_num_cities = max_num_cities
self.grid_mode = grid_mode
self.max_rails_between_cities = max_rails_between_cities
self.max_rails_in_city = max_rails_in_city
self.max_rail_pairs_in_city = max_rail_pairs_in_city
self.seed = seed # TODO: seed in constructor or generate?
......@@ -667,18 +667,20 @@ class SparseRailGen(RailGen):
rail_trans = RailEnvTransitions()
grid_map = GridTransitionMap(width=width, height=height, transitions=rail_trans)
# NEW : SCHED CONST (Pairs of rails (1,2,3 pairs))
min_nr_rail_pairs_in_city = 1 # (min pair must be 1)
rail_pairs_in_city = min_nr_rail_pairs_in_city if self.max_rail_pairs_in_city < min_nr_rail_pairs_in_city else self.max_rail_pairs_in_city # (pairs can be 1,2,3)
rails_between_cities = (rail_pairs_in_city*2) if self.max_rails_between_cities > (rail_pairs_in_city*2) else self.max_rails_between_cities
# We compute the city radius by the given max number of rails it can contain.
# The radius is equal to the number of tracks divided by 2
# We add 2 cells to avoid that track lenght is to short
city_padding = 2
# We use ceil if we get uneven numbers of city radius. This is to guarantee that all rails fit within the city.
city_radius = int(np.ceil((self.max_rails_in_city) / 2)) + city_padding
city_radius = int(np.ceil((rail_pairs_in_city*2) / 2)) + city_padding
vector_field = np.zeros(shape=(height, width)) - 1.
min_nr_rails_in_city = 2
rails_in_city = min_nr_rails_in_city if self.max_rails_in_city < min_nr_rails_in_city else self.max_rails_in_city
rails_between_cities = rails_in_city if self.max_rails_between_cities > rails_in_city else self.max_rails_between_cities
# Calculate the max number of cities allowed
# and reduce the number of cities to build to avoid problems
max_feasible_cities = min(self.max_num_cities,
......@@ -709,7 +711,7 @@ class SparseRailGen(RailGen):
inner_connection_points, outer_connection_points, city_orientations, city_cells = \
self._generate_city_connection_points(
city_positions, city_radius, vector_field, rails_between_cities,
rails_in_city, np_random=np_random)
rail_pairs_in_city, np_random=np_random)
# Connect the cities through the connection points
inter_city_lines = self._connect_cities(city_positions, outer_connection_points, city_cells,
......@@ -831,7 +833,7 @@ class SparseRailGen(RailGen):
def _generate_city_connection_points(self, city_positions: IntVector2DArray, city_radius: int,
vector_field: IntVector2DArray, rails_between_cities: int,
rails_in_city: int = 2, np_random: RandomState = None) -> (
rail_pairs_in_city: int = 1, np_random: RandomState = None) -> (
List[List[List[IntVector2D]]],
List[List[List[IntVector2D]]],
List[np.ndarray],
......@@ -852,7 +854,7 @@ class SparseRailGen(RailGen):
Each cell contains the prefered orientation of cells. If no prefered orientation is present it is set to -1
rails_between_cities: int
Number of rails that connect out from the city
rails_in_city: int
rail_pairs_in_city: int
Number of rails within the city
Returns
......@@ -895,7 +897,8 @@ class SparseRailGen(RailGen):
city_cells.extend(self._get_cells_in_city(city_position, city_radius, city_orientations[-1], vector_field))
# set the number of tracks within a city, at least 2 tracks per city
connections_per_direction = np.zeros(4, dtype=int)
nr_of_connection_points = np_random.randint(2, rails_in_city + 1)
# NEW : SCHED CONST
nr_of_connection_points = np_random.randint(1, rail_pairs_in_city + 1) * 2 # can be (1,2,3)*2 = (2,4,6)
for idx in connection_sides_idx:
connections_per_direction[idx] = nr_of_connection_points
connection_points_coordinates_inner: List[List[IntVector2D]] = [[] for i in range(4)]
......
......@@ -142,43 +142,50 @@ class SparseSchedGen(BaseSchedGen):
agents_target = []
agents_direction = []
for agent_idx in range(num_agents):
for agent_pair_idx in range(0, num_agents, 2):
infeasible_agent = True
tries = 0
while infeasible_agent:
tries += 1
infeasible_agent = False
# Set target for agent
# Setlect 2 cities, find their num_stations and possible orientations
city_idx = np_random.choice(len(city_positions), 2, replace=False)
start_city = city_idx[0]
target_city = city_idx[1]
start_idx = np_random.choice(np.arange(len(train_stations[start_city])))
target_idx = np_random.choice(np.arange(len(train_stations[target_city])))
start = train_stations[start_city][start_idx]
target = train_stations[target_city][target_idx]
while start[1] % 2 != 0:
start_idx = np_random.choice(np.arange(len(train_stations[start_city])))
start = train_stations[start_city][start_idx]
while target[1] % 2 != 1:
target_idx = np_random.choice(np.arange(len(train_stations[target_city])))
target = train_stations[target_city][target_idx]
possible_orientations = [city_orientation[start_city],
(city_orientation[start_city] + 2) % 4]
agent_orientation = np_random.choice(possible_orientations)
if not rail.check_path_exists(start[0], agent_orientation, target[0]):
agent_orientation = (agent_orientation + 2) % 4
if not (rail.check_path_exists(start[0], agent_orientation, target[0])):
infeasible_agent = True
city1 = city_idx[0]
city2 = city_idx[1]
city1_num_stations = len(train_stations[city1])
city2_num_stations = len(train_stations[city2])
city1_possible_orientations = [city_orientation[city1],
(city_orientation[city1] + 2) % 4]
city2_possible_orientations = [city_orientation[city2],
(city_orientation[city2] + 2) % 4]
# Agent 1 : city1 > city2, Agent 2: city2 > city1
agent1_start_idx = ((2 * np_random.randint(0, 10))) % city1_num_stations
agent1_target_idx = ((2 * np_random.randint(0, 10)) + 1) % city2_num_stations
agent2_start_idx = ((2 * np_random.randint(0, 10))) % city2_num_stations
agent2_target_idx = ((2 * np_random.randint(0, 10)) + 1) % city1_num_stations
agent1_start = train_stations[city1][agent1_start_idx]
agent1_target = train_stations[city2][agent1_target_idx]
agent2_start = train_stations[city2][agent2_start_idx]
agent2_target = train_stations[city1][agent2_target_idx]
agent1_orientation = np_random.choice(city1_possible_orientations)
agent2_orientation = np_random.choice(city2_possible_orientations)
# check path exists then break if tries > 100
if tries >= 100:
warnings.warn("Did not find any possible path, check your parameters!!!")
break
agents_position.append((start[0][0], start[0][1]))
agents_target.append((target[0][0], target[0][1]))
agents_direction.append(agent_orientation)
# Orient the agent correctly
# agent1 details
agents_position.append((agent1_start[0][0], agent1_start[0][1]))
agents_target.append((agent1_target[0][0], agent1_target[0][1]))
agents_direction.append(agent1_orientation)
# agent2 details
agents_position.append((agent2_start[0][0], agent2_start[0][1]))
agents_target.append((agent2_target[0][0], agent2_target[0][1]))
agents_direction.append(agent2_orientation)
if self.speed_ratio_map:
speeds = speed_initialization_helper(num_agents, self.speed_ratio_map, seed=_runtime_seed, np_random=np_random)
......
......@@ -5,12 +5,12 @@ import warnings
from typing import Tuple, List, Callable, Mapping, Optional, Any
import numpy as np
from numpy.core.fromnumeric import shape
from numpy.random.mtrand import RandomState
from flatland.envs.agent_utils import EnvAgent
from flatland.envs.schedule_utils import Schedule
from flatland.envs.distance_map import DistanceMap
from flatland.envs.rail_env_shortest_paths import get_shortest_paths
# #### DATA COLLECTION *************************
# import termplotlib as tpl
......@@ -40,7 +40,6 @@ def schedule_time_generator(agents: List[EnvAgent], config_speeds: List[float],
end_buffer_multiplier = 0.05
mean_shortest_path_multiplier = 0.2
from flatland.envs.rail_env_shortest_paths import get_shortest_paths
shortest_paths = get_shortest_paths(distance_map)
shortest_paths_lengths = [len(v) for k,v in shortest_paths.items()]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment