diff --git a/flatland/envs/env_utils.py b/flatland/envs/env_utils.py index fc2cdfba3b154e4da939b4294ec04d30176a3ed1..35e6560818acb0d5d7b2bf56bfd8feb33f26c87a 100644 --- a/flatland/envs/env_utils.py +++ b/flatland/envs/env_utils.py @@ -94,6 +94,7 @@ def coordinate_to_position(width, coords): position.append((t[1] * width + t[0])) return np.asarray(position).flatten() + class AStarNode(): """A node class for A* Pathfinding""" diff --git a/flatland/envs/observations.py b/flatland/envs/observations.py index 4b598c9336b2ca195ea26e5faaa5d596ce9d9eee..23a95ad63a798a7cc58e7272297e359c5c0f1f46 100644 --- a/flatland/envs/observations.py +++ b/flatland/envs/observations.py @@ -174,11 +174,11 @@ class TreeObsForRailEnv(ObservationBuilder): in the `handles' list. """ - if self.predictor: self.predicted_pos = {} self.predicted_dir = {} self.predictions = self.predictor.get() + for t in range(len(self.predictions[0])): pos_list = [] dir_list = [] @@ -187,6 +187,10 @@ class TreeObsForRailEnv(ObservationBuilder): dir_list.append(self.predictions[a][t][3]) self.predicted_pos.update({t: coordinate_to_position(self.env.width, pos_list)}) self.predicted_dir.update({t: dir_list}) + + pred_pos = np.concatenate([[x[:, 1:3]] for x in list(self.predictions.values())], axis=0) + pred_pos = list(map(list, zip(*pred_pos))) + observations = {} for h in handles: observations[h] = self.get(h) @@ -325,6 +329,7 @@ class TreeObsForRailEnv(ObservationBuilder): other_agent_opposite_direction += 1 if self.predictor: + continue # Register possible conflict if position in self.location_has_target: diff --git a/flatland/utils/graphics_layer.py b/flatland/utils/graphics_layer.py index d00d8b3ed41ff03a39bea64111f6b56032a0b2f8..ed92249ca422fa837a447f2765c70864f79c00a8 100644 --- a/flatland/utils/graphics_layer.py +++ b/flatland/utils/graphics_layer.py @@ -82,6 +82,5 @@ class GraphicsLayer(object): def resize(self, env): pass - - def build_background_map(self,dTargets): + def build_background_map(self, dTargets): pass diff --git a/flatland/utils/graphics_pil.py b/flatland/utils/graphics_pil.py index f8c96f1bd3d052aa5238ac563044acb6995e23a1..4019bb6d913a3bab1b57a9346c1196d634d18c1c 100644 --- a/flatland/utils/graphics_pil.py +++ b/flatland/utils/graphics_pil.py @@ -79,20 +79,18 @@ class PILGL(GraphicsLayer): self.firstFrame = True self.create_layers() - - def build_background_map(self,dTargets): + def build_background_map(self, dTargets): self.background_grid = np.zeros(shape=(self.width, self.height)) for x in range(self.width): for y in range(self.height): - distance = int(np.floor(np.sqrt(self.width*2.0 + self.height))) + distance = int(np.floor(np.sqrt(self.width * 2.0 + self.height))) for rc in dTargets: r = rc[1] c = rc[0] - d = int(np.floor(np.sqrt((x-r)**2 + (y-c)**2))) - distance = min(d,distance) + d = int(np.floor(np.sqrt((x - r) ** 2 + (y - c) ** 2))) + distance = min(d, distance) self.background_grid[x][y] = distance - def rgb_s2i(self, sRGB): """ convert a hex RGB string like 0091ea to 3-tuple of ints """ return tuple(int(sRGB[iRGB * 2:iRGB * 2 + 2], 16) for iRGB in [0, 1, 2]) @@ -236,7 +234,6 @@ class PILSVG(PILGL): self.lwAgents = [] self.agents_prev = [] - self.loadBuildingSVGs() self.loadScenerySVGs() self.loadRailSVGs() @@ -273,12 +270,18 @@ class PILSVG(PILGL): pil_img = Image.open(fIn) return pil_img - - def loadBuildingSVGs(self): dBuildingFiles = [ "Buildings/Bank.svg", "Buildings/Bar.svg", + "Buildings/Wohnhaus.svg", + "Buildings/Hochhaus.svg", + "Buildings/Hotel.svg", + "Buildings/Office.svg", + "Buildings/Polizei.svg", + "Buildings/Post.svg", + "Buildings/Supermarkt.svg", + "Buildings/Tankstelle.svg", "Buildings/Fabrik_A.svg", "Buildings/Fabrik_B.svg", "Buildings/Fabrik_C.svg", @@ -288,18 +291,14 @@ class PILSVG(PILGL): "Buildings/Fabrik_G.svg", "Buildings/Fabrik_H.svg", "Buildings/Fabrik_I.svg", - "Buildings/Hochhaus.svg", - "Buildings/Hotel.svg", - "Buildings/Office.svg", - "Buildings/Polizei.svg", - "Buildings/Post.svg", - "Buildings/Supermarkt.svg", - "Buildings/Tankstelle.svg", - "Buildings/Wohnhaus.svg"] + ] + + imgBg = self.pilFromSvgFile('svg', "Background_city.svg") self.dBuildings = [] for sFile in dBuildingFiles: - img = self.pilFromSvgFile('svg',sFile) + img = self.pilFromSvgFile('svg', sFile) + img = Image.alpha_composite(imgBg, img) self.dBuildings.append(img) def loadScenerySVGs(self): @@ -316,16 +315,20 @@ class PILSVG(PILGL): "Scenery/Bergwelt_A_Teil_2_mitte.svg", "Scenery/Bergwelt_A_Teil_3_rechts.svg", ] + + imgBg = self.pilFromSvgFile('svg', "Background_Light_green.svg") + self.dScenery = [] for sFile in dSceneryFiles: - img = self.pilFromSvgFile('svg',sFile) + img = self.pilFromSvgFile('svg', sFile) + img = Image.alpha_composite(imgBg, img) self.dScenery.append(img) def loadRailSVGs(self): """ Load the rail SVG images, apply rotations, and store as PIL images. """ dRailFiles = { - "": "Background_#91D1DD.svg", + "": "Background_Light_green.svg", "WE": "Gleis_Deadend.svg", "WW EE NN SS": "Gleis_Diamond_Crossing.svg", "WW EE": "Gleis_horizontal.svg", @@ -355,16 +358,19 @@ class PILSVG(PILGL): "NN SS": "Bahnhof_#d50000_Gleis_vertikal.svg"} # Dict of rail cell images indexed by binary transitions - self.dPilRail = self.loadSVGs(dRailFiles, rotate=True) + self.dPilRail = self.loadSVGs(dRailFiles, rotate=True, backgroundImage="Background_rail.svg", + whitefilter="Background_white_filter.svg") # Load the target files (which have rails and transitions of their own) # They are indexed by (binTrans, iAgent), ie a tuple of the binary transition and the agent index - dPilRail2 = self.loadSVGs(dTargetFiles, rotate=False, agent_colors=self.ltAgentColors) + dPilRail2 = self.loadSVGs(dTargetFiles, rotate=False, agent_colors=self.ltAgentColors, + backgroundImage="Background_rail.svg", + whitefilter="Background_white_filter.svg") # Merge them with the regular rails. # https://stackoverflow.com/questions/38987/how-to-merge-two-dictionaries-in-a-single-expression self.dPilRail = {**self.dPilRail, **dPilRail2} - def loadSVGs(self, dDirFile, rotate=False, agent_colors=False): + def loadSVGs(self, dDirFile, rotate=False, agent_colors=False, backgroundImage=None, whitefilter=None): dPil = {} transitions = RailEnvTransitions() @@ -387,6 +393,14 @@ class PILSVG(PILGL): pilRail = self.pilFromSvgFile('svg', sFile) + if backgroundImage is not None: + imgBg = self.pilFromSvgFile('svg', backgroundImage) + pilRail = Image.alpha_composite(imgBg, pilRail) + + if whitefilter is not None: + imgBg = self.pilFromSvgFile('svg', whitefilter) + pilRail = Image.alpha_composite(pilRail, imgBg) + if rotate: # For rotations, we also store the base image dPil[binTrans] = pilRail @@ -412,14 +426,19 @@ class PILSVG(PILGL): if binTrans in self.dPilRail: pilTrack = self.dPilRail[binTrans] - if binTrans == 0 : + if binTrans == 0: if self.background_grid[col][row] < 4: a = int(self.background_grid[col][row]) a = a % len(self.dBuildings) - pilTrack = self.dBuildings[a] - else: - a = int(self.background_grid[col][row]) - 4 + if (col + row) % 10 > 2: + pilTrack = self.dScenery[0] + else: + pilTrack = self.dBuildings[a] + elif (self.background_grid[col][row] > 5) or ((col ** 3 + row ** 2 + col * row) % 10 == 0): + a = int(self.background_grid[col][row]) - 5 a = a % len(self.dScenery) + if (col + row + col * row) % 10 > 2: + a = 0 pilTrack = self.dScenery[a] self.drawImageRC(pilTrack, (row, col)) diff --git a/flatland/utils/rendertools.py b/flatland/utils/rendertools.py index 937580f4469aec68942f04dbaadf50b5ee2f40bb..9b04f9c1a536183bddc6b4618e01cc2c702d09ad 100644 --- a/flatland/utils/rendertools.py +++ b/flatland/utils/rendertools.py @@ -47,7 +47,6 @@ class RenderTool(object): self.new_rail = True self.update_background() - def update_background(self): # create background map dTargets = {} @@ -509,19 +508,19 @@ class RenderTool(object): ) def renderEnv(self, - show=False, # whether to call matplotlib show() or equivalent after completion - # use false when calling from Jupyter. (and matplotlib no longer supported!) - curves=True, # draw turns as curves instead of straight diagonal lines - spacing=False, # defunct - size of spacing between rails - arrows=False, # defunct - draw arrows on rail lines - agents=True, # whether to include agents - show_observations=True, # whether to include observations - sRailColor="gray", # color to use in drawing rails (not used with SVG) - frames=False, # frame counter to show (intended since invocation) - iEpisode=None, # int episode number to show - iStep=None, # int step number to show in image - iSelectedAgent=None, # indicate which agent is "selected" in the editor - action_dict=None): # defunct - was used to indicate agent intention to turn + show=False, # whether to call matplotlib show() or equivalent after completion + # use false when calling from Jupyter. (and matplotlib no longer supported!) + curves=True, # draw turns as curves instead of straight diagonal lines + spacing=False, # defunct - size of spacing between rails + arrows=False, # defunct - draw arrows on rail lines + agents=True, # whether to include agents + show_observations=True, # whether to include observations + sRailColor="gray", # color to use in drawing rails (not used with SVG) + frames=False, # frame counter to show (intended since invocation) + iEpisode=None, # int episode number to show + iStep=None, # int step number to show in image + iSelectedAgent=None, # indicate which agent is "selected" in the editor + action_dict=None): # defunct - was used to indicate agent intention to turn """ Draw the environment using the GraphicsLayer this RenderTool was created with. (Use show=False from a Jupyter notebook with %matplotlib inline) """ diff --git a/notebooks/Scene_Editor.ipynb b/notebooks/Scene_Editor.ipynb index 7a13a49202dcb2f836e8842a84cccbf2b692599f..250ad48a5d37bd875527abc8e6a01d6c7941827b 100644 --- a/notebooks/Scene_Editor.ipynb +++ b/notebooks/Scene_Editor.ipynb @@ -100,7 +100,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "2460d8e561a3407d8fe2a6f28773bc04", + "model_id": "7783247e5f2146e293236d2426248f90", "version_major": 2, "version_minor": 0 }, diff --git a/svg/Background_Light_green.svg b/svg/Background_Light_green.svg new file mode 100644 index 0000000000000000000000000000000000000000..613995a291c91d514a2ffee798028a04873d6ba4 --- /dev/null +++ b/svg/Background_Light_green.svg @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="Ebene_1" + x="0px" + y="0px" + viewBox="0 0 240 240" + style="enable-background:new 0 0 240 240;" + xml:space="preserve" + sodipodi:docname="Background_#DEBDA0 - Kopie.svg" + inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata + id="metadata11"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage"/></cc:Work></rdf:RDF></metadata> + <defs + id="defs9"/> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1137" + id="namedview7" + showgrid="false" + inkscape:zoom="0.98333333" + inkscape:cx="120" + inkscape:cy="120" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:window-maximized="1" + inkscape:current-layer="Ebene_1"/> + <style + type="text/css" + id="style2"> + .st0{fill:#DEBDA0;} +</style> + + <rect + style="fill:#eef4d7" + id="rect13" + width="242.03391" + height="238.98306" + x="3.2327943e-08" + y="-1.1314779e-07"/></svg> diff --git a/svg/Background_city.svg b/svg/Background_city.svg new file mode 100644 index 0000000000000000000000000000000000000000..ba5d2ce94f3b025801108abe0900daf206e01c6c --- /dev/null +++ b/svg/Background_city.svg @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="Ebene_1" + x="0px" + y="0px" + viewBox="0 0 240 240" + style="enable-background:new 0 0 240 240;" + xml:space="preserve" + sodipodi:docname="Background_Light_gray.svg" + inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata + id="metadata11"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage"/></cc:Work></rdf:RDF></metadata> + <defs + id="defs9"/> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1137" + id="namedview7" + showgrid="false" + inkscape:zoom="0.98333333" + inkscape:cx="-102.20339" + inkscape:cy="120" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:window-maximized="1" + inkscape:current-layer="Ebene_1"/> + <style + type="text/css" + id="style2"> + .st0{fill:#DEBDA0;} +</style> + + <rect + style="fill:#fdf7fa;fill-opacity:1" + id="rect13" + width="242.03391" + height="238.98306" + x="3.2327943e-08" + y="-1.1314779e-07"/></svg> diff --git a/svg/Background_rail.svg b/svg/Background_rail.svg new file mode 100644 index 0000000000000000000000000000000000000000..e1d70666299cc14b3d82450ba4817fd681bb1495 --- /dev/null +++ b/svg/Background_rail.svg @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="Ebene_1" + x="0px" + y="0px" + viewBox="0 0 240 240" + style="enable-background:new 0 0 240 240;" + xml:space="preserve" + sodipodi:docname="Background_rail.svg" + inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata + id="metadata11"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage"/></cc:Work></rdf:RDF></metadata> + <defs + id="defs9"/> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1137" + id="namedview7" + showgrid="false" + inkscape:zoom="0.98333333" + inkscape:cx="-362.54237" + inkscape:cy="120" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:window-maximized="1" + inkscape:current-layer="Ebene_1"/> + <style + type="text/css" + id="style2"> + .st0{fill:#DEBDA0;} +</style> + + <rect + style="fill:#fbf6f7;fill-opacity:1" + id="rect13" + width="242.03391" + height="238.98306" + x="3.2327943e-08" + y="-1.1314779e-07"/></svg> diff --git a/svg/Background_white_filter.svg b/svg/Background_white_filter.svg new file mode 100644 index 0000000000000000000000000000000000000000..895a97a513341decfe0f348172f5e05722984ce0 --- /dev/null +++ b/svg/Background_white_filter.svg @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="Ebene_1" + x="0px" + y="0px" + viewBox="0 0 240 240" + style="enable-background:new 0 0 240 240;" + xml:space="preserve" + sodipodi:docname="Background_white_filter.svg" + inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata + id="metadata11"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage"/></cc:Work></rdf:RDF></metadata> + <defs + id="defs9"/> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1137" + id="namedview7" + showgrid="false" + inkscape:zoom="0.98333333" + inkscape:cx="-324.40678" + inkscape:cy="120" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:window-maximized="1" + inkscape:current-layer="Ebene_1"/> + <style + type="text/css" + id="style2"> + .st0{fill:#DEBDA0;} +</style> + + <rect + style="fill:#ffffff;fill-opacity:0.50196081" + id="rect13" + width="242.03391" + height="238.98306" + x="3.2327943e-08" + y="-1.1314779e-07"/></svg>