diff --git a/examples/flatland_2_0_example.py b/examples/flatland_2_0_example.py
index 1caa0aa943f564ba6a10f87f3efceb8233248fd7..5078af158ed9cb183978f83b505b5b1b291cb4f6 100644
--- a/examples/flatland_2_0_example.py
+++ b/examples/flatland_2_0_example.py
@@ -18,7 +18,6 @@ stochastic_data = {'prop_malfunction': 0.5,  # Percentage of defective agents
                    'max_duration': 10  # Max duration of malfunction
                    }
 
-
 TreeObservation = TreeObsForRailEnv(max_depth=2, predictor=ShortestPathPredictorForRailEnv())
 env = RailEnv(width=10,
               height=10,
@@ -106,7 +105,10 @@ for trials in range(1, n_trials + 1):
         # reward and whether their are done
         next_obs, all_rewards, done, _ = env.step(action_dict)
         env_renderer.render_env(show=True, show_observations=False, show_predictions=False)
-        env_renderer.gl.save_image("./Images/flatland_2_0_frame_{:04d}.bmp".format(frame_step))
+        try:
+            env_renderer.gl.save_image("./../rendering/flatland_2_0_frame_{:04d}.bmp".format(frame_step))
+        except:
+            print("Path not found: ./../rendering/")
         frame_step += 1
         # Update replay buffer and train agent
         for a in range(env.get_num_agents()):
diff --git a/flatland/envs/generators.py b/flatland/envs/generators.py
index 6049e6db3f0aa1680934314a95c2e1533a634003..aba4303739494a6fef5305158fde60c7f972fb60 100644
--- a/flatland/envs/generators.py
+++ b/flatland/envs/generators.py
@@ -543,7 +543,7 @@ def random_rail_generator(cell_type_relative_proportion=[1.0] * 11):
     return generator
 
 
-def realistic_rail_generator(nr_start_goal=1, seed=0):
+def realistic_rail_generator(nr_start_goal=1, seed=0, add_max_dead_end=4, two_track_back_bone=True):
     """
     Parameters
     -------
@@ -670,76 +670,154 @@ def realistic_rail_generator(nr_start_goal=1, seed=0):
 
         np.random.seed(seed + num_resets)
 
-        max_n_track_seg = np.random.choice([3, 4, 5])
+        max_n_track_seg = np.random.choice(np.arange(3, int(height / 2))) + int(two_track_back_bone)
         x_offsets = np.arange(0, height, max_n_track_seg).astype(int)
 
-        agents_positions_forward = []
-        agents_directions_forward = []
-        agents_positions_backward = []
-        agents_directions_backward = []
+        agents_positions = []
+        agents_directions = []
         agents_targets = []
 
-        idx_forward = []
-        idx_backward = []
-
-        idx_target = 0
         for off_set_loop in range(len(x_offsets)):
             off_set = x_offsets[off_set_loop]
             # second track
-            data = np.arange(int((width - 4 - max_n_track_seg) / max_n_track_seg)) * max_n_track_seg + 4
-            n_track_seg = np.random.choice(max_n_track_seg) + 1
+            data = np.arange(2, width - 2)
+            n_track_seg = np.random.choice([1,2])
+
+            track_2 = False
+            if two_track_back_bone:
+                if off_set + 1 < height:
+                    start_track = (off_set + 1, int((off_set_loop) % 2) * int(two_track_back_bone))
+                    goal_track = (off_set + 1, width - 1 - int((off_set_loop + 1) % 2) * int(two_track_back_bone))
+                    new_path = connect_rail(rail_trans, rail_array, start_track, goal_track)
+                    if len(new_path):
+                        track_2 = True
 
-            start_track = (off_set, 0)
-            goal_track = (off_set, width - 1)
+            start_track = (off_set, int((off_set_loop + 1) % 2) * int(two_track_back_bone) * int(track_2))
+            goal_track = (off_set, width - 1 - int((off_set_loop) % 2) * int(two_track_back_bone) * int(track_2))
             new_path = connect_rail(rail_trans, rail_array, start_track, goal_track)
 
-            # track one (full track : left right)
-            if off_set_loop > 0:
-                if off_set_loop % 2 == 1:
-                    start_track = (x_offsets[off_set_loop - 1] + 1, width - 1)
-                    goal_track = (x_offsets[off_set_loop] - 1, width - 1)
-                    new_path = connect_rail(rail_trans, rail_array, start_track, goal_track)
-
-                    add_rail(width, height, grid_map,
-                             (x_offsets[off_set_loop - 1], width - 2),
-                             (x_offsets[off_set_loop - 1], width - 1),
-                             (x_offsets[off_set_loop - 1] + 1, width - 1))
-                    add_rail(width, height, grid_map,
-                             (x_offsets[off_set_loop], width - 2),
-                             (x_offsets[off_set_loop], width - 1),
-                             (x_offsets[off_set_loop] - 1, width - 1))
-                    add_rail(width, height, grid_map,
-                             (x_offsets[off_set_loop - 1], width - 1),
-                             (x_offsets[off_set_loop - 1] + 1, width - 1),
-                             (x_offsets[off_set_loop - 1] + 2, width - 1))
-                    add_rail(width, height, grid_map,
-                             (x_offsets[off_set_loop], width - 1),
-                             (x_offsets[off_set_loop] - 1, width - 1),
-                             (x_offsets[off_set_loop] - 2, width - 1))
+            if track_2:
+                if np.random.random() < 0.75:
+                    c = (off_set, 3)
+                    if np.random.random() < 0.5:
+                        make_switch_e_w(width, height, grid_map, c)
+                    else:
+                        make_switch_w_e(width, height, grid_map, c)
+                if np.random.random() < 0.5:
+                    c = (off_set, width - 3)
+                    if np.random.random() < 0.5:
+                        make_switch_e_w(width, height, grid_map, c)
+                    else:
+                        make_switch_w_e(width, height, grid_map, c)
 
-                else:
-                    start_track = (x_offsets[off_set_loop - 1] + 1, 0)
-                    goal_track = (x_offsets[off_set_loop] - 1, 0)
-                    new_path = connect_rail(rail_trans, rail_array, start_track, goal_track)
+            # track one (full track : left right)
+            for two_track_back_bone_loop in range(1 + int(track_2) * int(two_track_back_bone)):
+                if off_set_loop > 0:
+                    if off_set_loop % 2 == 1:
+                        start_track = (
+                            x_offsets[off_set_loop - 1] + 1 + int(two_track_back_bone_loop),
+                            width - 1 - int(two_track_back_bone_loop))
+                        goal_track = (x_offsets[off_set_loop] - 1 + int(two_track_back_bone) * int(track_2) - int(
+                            two_track_back_bone_loop),
+                                      width - 1 - int(
+                                          two_track_back_bone_loop))
+                        new_path = connect_rail(rail_trans, rail_array, start_track, goal_track)
+
+                        if (goal_track[1] - start_track[1]) > 1:
+                            add_pos = (
+                                int((start_track[0] + goal_track[0]) / 2), int((start_track[1] + goal_track[1]) / 2))
+                            agents_positions.append(add_pos)
+                            agents_directions.append(([1, 3][off_set_loop % 2]))
+                            agents_targets.append(add_pos)
+
+                        add_rail(width, height, grid_map,
+                                 (x_offsets[off_set_loop - 1] + int(two_track_back_bone_loop),
+                                  width - 2 - int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop - 1] + int(two_track_back_bone_loop),
+                                  width - 1 - int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop - 1] + int(two_track_back_bone_loop) + 1,
+                                  width - 1 - int(two_track_back_bone_loop)))
+                        add_rail(width, height, grid_map,
+                                 (x_offsets[off_set_loop] - int(two_track_back_bone_loop) + int(
+                                     two_track_back_bone) * int(track_2),
+                                  width - 2 - int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop] - int(two_track_back_bone_loop) + int(
+                                     two_track_back_bone) * int(track_2),
+                                  width - 1 - int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop] - int(two_track_back_bone_loop) + int(
+                                     two_track_back_bone) * int(track_2) - 1,
+                                  width - 1 - int(two_track_back_bone_loop)))
+                        add_rail(width, height, grid_map,
+                                 (x_offsets[off_set_loop - 1] + int(two_track_back_bone_loop),
+                                  width - 1 - int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop - 1] + int(two_track_back_bone_loop) + 1,
+                                  width - 1 - int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop - 1] + int(two_track_back_bone_loop) + 2,
+                                  width - 1 - int(two_track_back_bone_loop)))
+                        add_rail(width, height, grid_map,
+                                 (x_offsets[off_set_loop] - int(two_track_back_bone_loop) + int(
+                                     two_track_back_bone) * int(track_2),
+                                  width - 1 - int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop] - int(two_track_back_bone_loop) + int(
+                                     two_track_back_bone) * int(track_2) - 1,
+                                  width - 1 - int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop] - int(two_track_back_bone_loop) + int(
+                                     two_track_back_bone) * int(track_2) - 2,
+                                  width - 1 - int(two_track_back_bone_loop)))
 
-                    add_rail(width, height, grid_map,
-                             (x_offsets[off_set_loop - 1], 1),
-                             (x_offsets[off_set_loop - 1], 0),
-                             (x_offsets[off_set_loop - 1] + 1, 0))
-                    add_rail(width, height, grid_map,
-                             (x_offsets[off_set_loop], 1),
-                             (x_offsets[off_set_loop], 0),
-                             (x_offsets[off_set_loop] - 1, 0))
-                    add_rail(width, height, grid_map,
-                             (x_offsets[off_set_loop - 1], 0),
-                             (x_offsets[off_set_loop - 1] + 1, 0),
-                             (x_offsets[off_set_loop - 1] + 2, 0))
-                    add_rail(width, height, grid_map,
-                             (x_offsets[off_set_loop], 0),
-                             (x_offsets[off_set_loop] - 1, 0),
-                             (x_offsets[off_set_loop] - 2, 0))
+                    else:
+                        start_track = (
+                            x_offsets[off_set_loop - 1] + 1 + int(two_track_back_bone_loop),
+                            int(two_track_back_bone_loop))
+                        goal_track = (x_offsets[off_set_loop] - 1 + int(two_track_back_bone) * int(track_2) - int(
+                            two_track_back_bone_loop),
+                                      int(two_track_back_bone_loop))
+                        new_path = connect_rail(rail_trans, rail_array, start_track, goal_track)
+
+                        if (goal_track[1] - start_track[1]) > 1:
+                            add_pos = (
+                                int((start_track[0] + goal_track[0]) / 2), int((start_track[1] + goal_track[1]) / 2))
+                            agents_positions.append(add_pos)
+                            agents_directions.append(([1, 3][off_set_loop % 2]))
+                            agents_targets.append(add_pos)
+
+                        add_rail(width, height, grid_map,
+                                 (x_offsets[off_set_loop - 1] + int(two_track_back_bone_loop),
+                                  1 + int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop - 1] + int(two_track_back_bone_loop),
+                                  0 + int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop - 1] + int(two_track_back_bone_loop) + 1,
+                                  0 + int(two_track_back_bone_loop)))
+                        add_rail(width, height, grid_map,
+                                 (x_offsets[off_set_loop] - int(two_track_back_bone_loop) + int(
+                                     two_track_back_bone) * int(track_2),
+                                  1 + int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop] - int(two_track_back_bone_loop) + int(
+                                     two_track_back_bone) * int(track_2),
+                                  0 + int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop] - int(two_track_back_bone_loop) + int(
+                                     two_track_back_bone) * int(track_2) - 1,
+                                  0 + int(two_track_back_bone_loop)))
+                        add_rail(width, height, grid_map,
+                                 (x_offsets[off_set_loop - 1] + int(two_track_back_bone_loop),
+                                  0 + int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop - 1] + int(two_track_back_bone_loop) + 1,
+                                  0 + int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop - 1] + int(two_track_back_bone_loop) + 2,
+                                  0 + int(two_track_back_bone_loop)))
+                        add_rail(width, height, grid_map,
+                                 (x_offsets[off_set_loop] - int(two_track_back_bone_loop) + int(
+                                     two_track_back_bone) * int(track_2),
+                                  0 + int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop] - int(two_track_back_bone_loop) + int(
+                                     two_track_back_bone) * int(track_2) - 1,
+                                  0 + int(two_track_back_bone_loop)),
+                                 (x_offsets[off_set_loop] - int(two_track_back_bone_loop) + int(
+                                     two_track_back_bone) * int(track_2) - 2,
+                                  0 + int(two_track_back_bone_loop)))
 
             for nbr_track_loop in range(max_n_track_seg - 1):
+                n_track_seg = 1
                 if len(data) < 2 * n_track_seg + 1:
                     break
                 x = np.sort(np.random.choice(data, 2 * n_track_seg, False)).astype(int)
@@ -750,7 +828,8 @@ def realistic_rail_generator(nr_start_goal=1, seed=0):
                     goal = (
                         max(0, min(off_set + nbr_track_loop + 1, height - 1)),
                         max(0, min(x[2 * x_loop + 1], width - 1)))
-                    d = np.arange(x[2 * x_loop] + 1, x[2 * x_loop + 1] - 1, 2)
+
+                    d = np.arange(x[2 * x_loop] + 1, x[2 * x_loop + 1] - 1)
                     data.extend(d)
 
                     new_path = connect_rail(rail_trans, rail_array, start, goal)
@@ -761,26 +840,23 @@ def realistic_rail_generator(nr_start_goal=1, seed=0):
                         make_switch_w_e(width, height, grid_map, c)
 
                     add_pos = (int((start[0] + goal[0]) / 2), int((start[1] + goal[1]) / 2))
-                    if nbr_track_loop % 2 == 0:
-                        agents_positions_forward.append(add_pos)
-                        agents_directions_forward.append(([1, 3][off_set_loop % 2]))
-                        idx_forward.append(idx_target)
-                    else:
-                        agents_positions_backward.append(add_pos)
-                        agents_directions_backward.append(([1, 3][off_set_loop % 2]))
-                        idx_backward.append(idx_target)
-
-                    add_pos = (int((start[0] + goal[0]) / 2), int((2 * start[1] + goal[1]) / 3), idx_target)
+                    agents_positions.append(add_pos)
+                    agents_directions.append(([1, 3][off_set_loop % 2]))
+                    add_pos = (int((start[0] + goal[0]) / 2), int((2 * start[1] + goal[1]) / 3))
                     agents_targets.append(add_pos)
-                    idx_target += 1
 
-            add_max_dead_end = 20
-            for pos_y in np.random.choice(np.arange(width - 7) + 3, add_max_dead_end, False):
-                pos_x = off_set + 1
+        for off_set_loop in range(len(x_offsets)):
+            off_set = x_offsets[off_set_loop]
+            pos_ys = np.random.choice(np.arange(width - 7) + 4, min(width - 7, add_max_dead_end), False)
+            for pos_y in pos_ys:
+                pos_x = off_set + 1 + int(two_track_back_bone)
                 if pos_x < height - 1:
                     ok = True
-                    for k in range(6):
-                        c = (pos_x, pos_y - k + 1)
+                    for k in range(5):
+                        if two_track_back_bone:
+                            c = (pos_x - 1, pos_y - k + 2)
+                            ok &= grid_map.grid[c[0]][c[1]] == 1025
+                        c = (pos_x, pos_y - k + 2)
                         ok &= grid_map.grid[c[0]][c[1]] == 0
                     if ok:
                         if np.random.random() < 0.5:
@@ -790,6 +866,15 @@ def realistic_rail_generator(nr_start_goal=1, seed=0):
                             if len(new_path) > 0:
                                 c = (pos_x - 1, pos_y - 1)
                                 make_switch_e_w(width, height, grid_map, c)
+                                add_pos = (
+                                    int((goal_track[0] + start_track[0]) / 2),
+                                    int((goal_track[1] + start_track[1]) / 2))
+                                agents_positions.append(add_pos)
+                                agents_directions.append(3)
+                                add_pos = (
+                                    int((goal_track[0] + start_track[0]) / 2),
+                                    int((goal_track[1] + start_track[1]) / 2))
+                                agents_targets.append(add_pos)
                         else:
                             start_track = (pos_x, pos_y)
                             goal_track = (pos_x, pos_y - 2)
@@ -797,6 +882,15 @@ def realistic_rail_generator(nr_start_goal=1, seed=0):
                             if len(new_path) > 0:
                                 c = (pos_x - 1, pos_y + 1)
                                 make_switch_w_e(width, height, grid_map, c)
+                                add_pos = (
+                                    int((goal_track[0] + start_track[0]) / 2),
+                                    int((goal_track[1] + start_track[1]) / 2))
+                                agents_positions.append(add_pos)
+                                agents_directions.append(1)
+                                add_pos = (
+                                    int((goal_track[0] + start_track[0]) / 2),
+                                    int((goal_track[1] + start_track[1]) / 2))
+                                agents_targets.append(add_pos)
 
         agents_position = []
         agents_target = []
@@ -806,30 +900,15 @@ def realistic_rail_generator(nr_start_goal=1, seed=0):
             t = np.random.choice(range(len(agents_targets)))
             d = agents_targets[t]
             agents_targets.pop(t)
-            if d[2] < idx_target / 2:
-                if len(idx_backward) > 0:
-                    agents_target.append((d[0], d[1]))
-                    sel = np.random.choice(range(len(idx_backward)))
-                    # backward
-                    p = agents_positions_backward[sel]
-                    d = agents_directions_backward[sel]
-                    agents_positions_backward.pop(sel)
-                    agents_directions_backward.pop(sel)
-                    idx_backward.pop(sel)
-                    agents_position.append((p[0], p[1]))
-                    agents_direction.append(d)
-            else:
-                if len(idx_forward) > 0:
-                    agents_target.append((d[0], d[1]))
-                    sel = np.random.choice(range(len(idx_forward)))
-                    # forward
-                    p = agents_positions_forward[sel]
-                    d = agents_directions_forward[sel]
-                    agents_positions_forward.pop(sel)
-                    agents_directions_forward.pop(sel)
-                    idx_forward.pop(sel)
-                    agents_position.append((p[0], p[1]))
-                    agents_direction.append(d)
+            agents_target.append((d[0], d[1]))
+            sel = np.random.choice(range(len(agents_positions)))
+            # backward
+            p = agents_positions[sel]
+            d = agents_directions[sel]
+            agents_positions.pop(sel)
+            agents_directions.pop(sel)
+            agents_position.append((p[0], p[1]))
+            agents_direction.append(d)
 
         return grid_map, agents_position, agents_direction, agents_target, [1.0] * len(agents_position)
 
diff --git a/tests/test_flatland_env_sparse_rail_generator.py b/tests/test_flatland_env_sparse_rail_generator.py
index ca60237b93bb79ed9e3f44e50a4374347eb4481a..d329ac39b5b619c93f677bd756b275cb84eb8ad6 100644
--- a/tests/test_flatland_env_sparse_rail_generator.py
+++ b/tests/test_flatland_env_sparse_rail_generator.py
@@ -1,3 +1,5 @@
+import os
+
 import numpy as np
 
 from flatland.envs.generators import sparse_rail_generator, realistic_rail_generator
@@ -7,20 +9,31 @@ from flatland.utils.rendertools import RenderTool, AgentRenderVariant
 
 
 def test_realistic_rail_generator(vizualization_folder_name=None):
-    for test_loop in range(20):
+    for test_loop in range(50):
+        print("test_loop", test_loop)
         num_agents = np.random.randint(10, 30)
         env = RailEnv(width=np.random.randint(40, 80),
                       height=np.random.randint(10, 20),
-                      rail_generator=realistic_rail_generator(nr_start_goal=num_agents + 1, seed=test_loop),
+                      rail_generator=realistic_rail_generator(nr_start_goal=num_agents + 1,
+                                                              seed=test_loop,
+                                                              add_max_dead_end=4,
+                                                              two_track_back_bone=test_loop % 2 == 0),
                       number_of_agents=num_agents,
                       obs_builder_object=GlobalObsForRailEnv())
         # reset to initialize agents_static
         env_renderer = RenderTool(env, gl="PILSVG", agent_render_variant=AgentRenderVariant.ONE_STEP_BEHIND,
-                                  screen_height=1200,
-                                  screen_width=1600)
+                                  screen_height=600,
+                                  screen_width=800)
         env_renderer.render_env(show=True, show_observations=True, show_predictions=False)
+        if vizualization_folder_name is not None:
+            env_renderer.gl.save_image(
+                os.path.join(
+                    vizualization_folder_name,
+                    "flatland_frame_{:04d}.png".format(test_loop)
+                ))
         env_renderer.close_window()
 
+
 def test_sparse_rail_generator():
     env = RailEnv(width=50,
                   height=50,