Пример #1
0
def scenario_root(scenario_parent_path):
    # TODO: We may want to consider referencing to concrete scenarios in our tests
    #       rather than generating them. The benefit of generting however is that
    #       we can change the test criteria and scenario code in unison.
    scenario = Path(scenario_parent_path) / "cycles"
    scenario.mkdir()

    shutil.copyfile(
        Path(__file__).parent / "maps/6lane.net.xml", scenario / "map.net.xml")
    generate_glb_from_sumo_network(str(scenario / "map.net.xml"),
                                   str(scenario / "map.glb"))

    actors = [
        SocialAgentActor(
            name=f"non-interactive-agent-{speed}-v0",
            agent_locator="zoo.policies:non-interactive-agent-v0",
            policy_kwargs={"speed": speed},
        ) for speed in [10, 30, 80]
    ]

    for name, (edge_start, edge_end) in [
        ("group-1", ("edge-north-NS", "edge-south-NS")),
        ("group-2", ("edge-west-WE", "edge-east-WE")),
        ("group-3", ("edge-east-EW", "edge-west-EW")),
        ("group-4", ("edge-south-SN", "edge-north-SN")),
    ]:
        route = Route(begin=("edge-north-NS", 1, 0),
                      end=("edge-south-NS", 1, "max"))
        missions = [Mission(route=route)] * 2  # double up
        gen_social_agent_missions(
            scenario,
            social_agent_actor=actors,
            name=name,
            missions=missions,
        )

    gen_missions(
        scenario,
        missions=[
            Mission(
                Route(begin=("edge-west-WE", 0, 0),
                      end=("edge-east-WE", 0, "max")))
        ],
    )

    return scenario
Пример #2
0
def scenario_root():
    # TODO: We may want to consider referencing to concrete scenarios in our tests
    #       rather than generating them. The benefit of generting however is that
    #       we can change the test criteria and scenario code in unison.
    with temp_scenario(name="cycles",
                       map="maps/6lane.net.xml") as scenario_root:
        actors = [
            SocialAgentActor(
                name=f"non-interactive-agent-{speed}-v0",
                agent_locator="zoo.policies:non-interactive-agent-v0",
                policy_kwargs={"speed": speed},
            ) for speed in [10, 30, 80]
        ]

        for name, (edge_start, edge_end) in [
            ("group-1", ("edge-north-NS", "edge-south-NS")),
            ("group-2", ("edge-west-WE", "edge-east-WE")),
            ("group-3", ("edge-east-EW", "edge-west-EW")),
            ("group-4", ("edge-south-SN", "edge-north-SN")),
        ]:
            route = Route(begin=("edge-north-NS", 1, 0),
                          end=("edge-south-NS", 1, "max"))
            missions = [Mission(route=route)] * 2  # double up
            gen_social_agent_missions(
                scenario_root,
                social_agent_actor=actors,
                name=name,
                missions=missions,
            )

        gen_missions(
            scenario_root,
            missions=[
                Mission(
                    Route(begin=("edge-west-WE", 0, 0),
                          end=("edge-east-WE", 0, "max")))
            ],
        )
        yield scenario_root
Пример #3
0
    JunctionModel,
)

scenario_path = str(Path(__file__).parent)

sv_num = 30
seed = 42

# generate agent missions
gen_missions(
    scenario_path,
    [
        # start line and end line should be the same
        t.LapMission(
            t.Route(
                begin=("edge1", 0, 10), via=("edge0",), end=("edge1", (0, 1, 2), 10)
            ),
            num_laps=1,
        ),
    ],
    overwrite=True,
)

print(f"generate lap mission finished")

# generate social agent routes

impatient_car = TrafficActor(
    name="car",
    speed=Distribution(sigma=0.2, mean=0.5),
    lane_changing_model=LaneChangingModel(impatience=1, cooperative=0.25),
Пример #4
0
from smarts.sstudio import gen_traffic, gen_bubbles, gen_missions

scenario = str(Path(__file__).parent)

# Definition of a traffic flow
traffic = t.Traffic(
    flows=[
        t.Flow(
            route=t.Route(
                begin=("west", lane_idx, 10),
                end=("east", lane_idx, -10),
            ),
            rate=50,
            actors={
                t.TrafficActor("car"): 1,
            },
        )
        for lane_idx in range(3)
    ]
)

# The call to generate traffic
gen_traffic(scenario, traffic, name="basic")

gen_missions(
    scenario,
    [
        t.Mission(t.Route(begin=("west", 0, 0), end=("east", 0, "max"))),
    ],
)
Пример #5
0
    Flow,
    Route,
    RandomRoute,
    TrafficActor,
    Mission,
)

scenario = os.path.dirname(os.path.realpath(__file__))

agent_missions = [
    Mission(Route(begin=("left_in", 0, 80), end=("merged", (0, ), 40))),
    Mission(Route(begin=("left_in", 0, 50), end=("merged", (0, ), 40))),
    Mission(Route(begin=("ramp_in", 0, 80), end=("merged", (0, ), 60))),
    Mission(Route(begin=("ramp_in", 0, 50), end=("merged", (0, ), 60))),
]

gen_missions(scenario, agent_missions, overwrite=True)

gen_traffic(
    scenario,
    Traffic(flows=[
        Flow(
            route=RandomRoute(),
            rate=3600,
            actors={TrafficActor(name="car"): 1.0},
        )
    ]),
    name="random",
    overwrite=True,
)
Пример #6
0
def generate_left_turn_missions(
    mission,
    route_distributions,
    route_lanes,
    speed,
    map_dir,
    level_name,
    save_dir,
    stopwatcher_behavior,
    stopwatcher_route,
    seed,
    intersection_name,
    traffic_density,
):
    # dont worry about these seeds, theyre used by sumo
    sumo_seed = random.choice([0, 1, 2, 3, 4])
    stopwatcher_info = None
    stopwatcher_added = False
    if stopwatcher_behavior:
        stopwatcher_info = {
            "behavior": stopwatcher_behavior,
            "direction": get_direction(stopwatcher_route),
        }

    random.seed(seed)
    np.random.seed(seed)
    all_flows = []
    metadata = {"routes": {}, "total_vehicles": 0, "stopwatcher": None}

    scenario = save_dir + f"-flow-{seed}"

    # Remove old traffic route if it exists(otherwise, won't update to new flows)
    if os.path.exists(f"{scenario}/traffic/all.rou.xml"):
        shutil.rmtree(scenario)

    for route_key, route_info in route_distributions["routes"].items():
        # to skip None
        if route_info:
            if stopwatcher_behavior:  # put the ego on the side road
                ego_start_lane, ego_end_lane = 0, 0
                mission_start, mission_end = "south-side", "dead-end"
                ego_start_pos, ego_end_pos = 100, 5
                ego_num_lanes = 1
            else:
                mission_start, mission_end = mission["start"], mission["end"]
                ego_start_lane, ego_end_lane = (
                    route_lanes[mission_start] - 1,
                    route_lanes[mission_end] - 1,
                )
                ego_start_pos, ego_end_pos = (
                    random.randint(50, 120),
                    random.randint(50, 150),
                )
                ego_num_lanes = route_lanes[mission_start]

            ego_route = Route(
                begin=(f"edge-{mission_start}", ego_start_lane, ego_start_pos),
                end=(f"edge-{mission_end}", ego_end_lane, ego_end_pos),
            )
            flows, vehicles_log_info = generate_social_vehicles(
                ego_start_lane=ego_start_lane,
                route_distribution=route_info["distribution"],
                begin_time_init=route_info["begin_time_init"],
                num_vehicles=route_info["vehicles"],
                route_direction=get_direction(route_key),
                route_lanes=route_lanes,
                route_has_turn=route_info["has_turn"],
                start_end_on_different_lanes_probability=route_info[
                    "start_end_on_different_lanes_probability"],
                deadlock_optimization=route_info["deadlock_optimization"],
                stopwatcher_info=stopwatcher_info,
            )
            if (stopwatcher_behavior and len(flows) > 0 and
                    get_direction(route_key) == stopwatcher_info["direction"]):
                stopwatcher_added = True
                print(
                    f'stop watcher added to {get_direction(route_key)} flows among {route_info["vehicles"]} vehicles!'
                )
            all_flows.extend(flows)
            metadata["routes"][route_key] = vehicles_log_info
    scenario = save_dir + f"-flow-{seed}"
    if stopwatcher_behavior:
        if not stopwatcher_added and level_name != "no-traffic":
            print(
                f'There was no matching flows for stopwatcher, adding it to {stopwatcher_info["direction"]}.'
            )
            # vehicles_log_info[f'stopwatcher_{stopwatcher_info["behavior"]}']["count"] += 1
            all_flows.append(
                generate_stopwatcher(
                    stopwatcher_behavior=stopwatcher_info["behavior"],
                    stopwatcher_route=stopwatcher_info["direction"],
                    start_lane_id=0,
                    end_lane_id=0,
                ))
        scenario += f"-stopwatcher-{stopwatcher_info['behavior']}"

    copy_map_files(scenario, map_dir, speed)
    if stopwatcher_behavior or "ego_hijacking_params" not in route_distributions:
        gen_missions(scenario, [Mission(ego_route)])
    else:
        speed_m_per_s = float("".join(filter(str.isdigit, speed))) * 5.0 / 18.0
        hijacking_params = route_distributions["ego_hijacking_params"]
        zone_range = hijacking_params["zone_range"]
        waiting_time = hijacking_params["wait_to_hijack_limit_s"]
        start_time = hijacking_params["start_time"]

        if start_time == "default":
            start_time = random.randint((LANE_LENGTH // speed_m_per_s), 60)
        gen_missions(
            scenario,
            [
                Mission(
                    ego_route,
                    # optional: control hijacking time, place, and emission.
                    start_time=
                    start_time,  # when to start hijacking (might start later)
                    entry_tactic=TrapEntryTactic(
                        wait_to_hijack_limit_s=
                        waiting_time,  # when to give up on hijacking and start emitting a social vehicle instead
                        zone=MapZone(
                            start=(
                                f'edge-{mission["start"]}',
                                0,
                                ego_start_pos + zone_range[0],
                            ),
                            length=zone_range[1],
                            n_lanes=route_lanes[mission["start"]],
                        ),  # area to hijack
                        exclusion_prefixes=tuple(
                        ),  # vehicles to be excluded (check vehicle ids)
                    ),
                ),
            ],
        )

    traffic = Traffic(flows=all_flows)
    gen_traffic(scenario, traffic, name=f"all", seed=sumo_seed)
    # patch: remove route files from traffic folder to make intersection empty
    if traffic_density == "no-traffic":

        os.remove(f"{scenario}/traffic/all.rou.xml")
    if stopwatcher_behavior:
        metadata["stopwatcher"] = {
            "direction": stopwatcher_info["direction"],
            "behavior": stopwatcher_info["behavior"],
        }
    metadata["intersection"] = {
        "type": intersection_name[-1],
        "name": intersection_name,
    }
    metadata["total_vehicles"] = len(all_flows)
    metadata["seed"] = seed
    metadata["flow_id"] = f"flow_{seed}"
    with open(f"{scenario}/metadata.json", "w") as log:
        json.dump(metadata, log)
Пример #7
0
    JunctionModel,
)

scenario_path = str(Path(__file__).parent)

sv_num = 30
seed = 42

# generate agent missions
gen_missions(
    scenario_path,
    [
        t.LapMission(
            t.Route(
                begin=("gneE14", 0, 10),
                via=("edge-east-EN", "gneE48"),
                end=("gneE14", (0, 1), 10),
            ),
            num_laps=1,
        ),
    ],
    overwrite=True,
)

print(f"generate lap mission finished")

# generate social agent routes

impatient_car = TrafficActor(
    name="car",
    speed=Distribution(sigma=0.2, mean=0.5),
    lane_changing_model=LaneChangingModel(impatience=1, cooperative=0.25),
Пример #8
0
import os
import pickle
from smarts.sstudio import gen_missions, gen_social_agent_missions
from smarts.sstudio import types as t

scenario = os.path.dirname(os.path.realpath(__file__))

with open(os.environ["SOCIAL_AGENT_PATH"], "rb") as f:
    social_agent = pickle.load(f)

gen_social_agent_missions(
    scenario,
    social_agent_actor=social_agent,
    name=f"s-agent-{social_agent.name}",
    missions=[t.Mission(t.Route(begin=("E35-3", 2, 90), end=("E3-3s", 0, 30))),],
)

gen_missions(
    scenario, [t.Mission(t.Route(begin=("E3l-3", 1, 200), end=("E3-35", 1, 50))),],
)
Пример #9
0
gen_missions(
    scenario,
    [
        Mission(
            Route(begin=("edge-west-WE", 0, 10), end=("edge-south-NS", 0, 40)),
            entry_tactic=TrapEntryTactic(
                wait_to_hijack_limit_s=3,
                zone=MapZone(
                    start=("edge-west-WE", 0, 5),
                    length=30,
                    n_lanes=1,
                ),
            ),
        ),
        Mission(
            Route(begin=("edge-west-WE", 0, 10), end=("edge-west-WE", 0, 25)),
            entry_tactic=TrapEntryTactic(
                wait_to_hijack_limit_s=3,
                zone=MapZone(
                    start=("edge-west-WE", 0, 5),
                    length=30,
                    n_lanes=1,
                ),
            ),
        ),
        Mission(
            Route(begin=("edge-south-SN", 0, 30), end=("edge-west-EW", 0, 50)),
            entry_tactic=TrapEntryTactic(
                wait_to_hijack_limit_s=3,
                zone=MapZone(
                    start=("edge-south-SN", 0, 5),
                    length=30,
                    n_lanes=1,
                ),
            ),
        ),
    ],
)
Пример #10
0
gen_social_agent_missions(
    scenario,
    social_agent_actor=social_agent2,
    name=f"s-agent-{social_agent2.name}",
    missions=[Mission(RandomRoute())],
)

gen_social_agent_missions(
    scenario,
    social_agent_actor=social_agent1,
    name=f"s-agent-{social_agent1.name}",
    missions=[
        EndlessMission(begin=("edge-south-SN", 0, 30)),
        Mission(
            Route(begin=("edge-west-WE", 0, 10), end=("edge-east-WE", 0, 10))),
    ],
)

# Agent Missions
gen_missions(
    scenario=scenario,
    missions=[
        Mission(
            Route(begin=("edge-east-EW", 0, 10),
                  end=("edge-south-NS", 0, 10))),
        Mission(
            Route(begin=("edge-south-SN", 0, 10),
                  end=("edge-east-WE", 0, 10))),
    ],
)
Пример #11
0
    JunctionModel,
)

scenario_path = str(Path(__file__).parent)

sv_num = 13
seed = 345

# generate agent missions
gen_missions(
    scenario_path,
    [
        t.LapMission(
            t.Route(
                begin=("gneE9", 0, 10),
                via=("gneE5", "gneE7.141"),
                end=("gneE9", (0, 1), 10),
            ),
            num_laps=1,
        ),
    ],
    overwrite=True,
)

print(f"generate lap mission finished")

# generate social agent routes

impatient_car = TrafficActor(
    name="patient_car",
    speed=Distribution(sigma=0.2, mean=0.5),
    lane_changing_model=LaneChangingModel(impatience=1, cooperative=0.25),
Пример #12
0
    JunctionModel,
)

scenario_path = str(Path(__file__).parent)

sv_num = 30
seed = 42

# generate agent missions
gen_missions(
    scenario_path,
    [
        t.LapMission(
            t.Route(
                begin=("edge1", 0, 50),
                via=("edge0", ),
                end=("edge1", (0, 1, 2), 50),
            ),
            num_laps=1,
        ),
    ],
    overwrite=True,
)

print(f"generate lap mission finished")

# generate social agent routes

impatient_car = TrafficActor(
    name="car",
    speed=Distribution(sigma=0.2, mean=0.5),
    lane_changing_model=LaneChangingModel(impatience=1, cooperative=0.25),
Пример #13
0
    JunctionModel,
)

scenario_path = str(Path(__file__).parent)

sv_num = 30
seed = 42

# generate agent missions
gen_missions(
    scenario_path,
    [
        t.LapMission(
            t.Route(
                begin=("gneE92", 0, 10),
                via=("edge-south-SE", "gneE82", "gneE93"),
                end=("gneE92", (0,), 10),
            ),
            num_laps=1,
        ),
    ],
    overwrite=True,
)


print(f"generate lap mission finished")

# generate social agent routes

impatient_car = TrafficActor(
    name="car",
    speed=Distribution(sigma=0.2, mean=0.5),
Пример #14
0
print("generate social agent missions finished")


#########################################
# generate agent missions
#########################################

# generate agent Missions so agents will born in the same position after env reset()
# Otherwise, no defined agent mission will lead to agent born in different place after env reset()
for scenario, starting_edge in zip(scenario_paths, starting_edges):
    gen_missions(
        scenario=scenario,
        missions=[
            # edge_id, lane_index, offset
            EndlessMission(begin=(starting_edge, 0, 0),),
            # Mission(Route(begin=("edge-east", 0, 0), end=("edge-east", 0, -5))),
        ],
        overwrite=True,
    )

print("generate ego agent missions finished")


#########################################
# generate social vehicles
#########################################
sv_nums = [60, 60, 60, 60]

seed = 45
Пример #15
0
    JunctionModel,
)

scenario_path = str(Path(__file__).parent)

sv_num = 18
seed = 675

# generate agent missions
gen_missions(
    scenario_path,
    [
        t.LapMission(
            t.Route(
                begin=("gneE78", 0, 10),
                via=("edge-west-WS", "gneE61"),
                end=("gneE78", (0, 1), 10),
            ),
            num_laps=1,
        ),
    ],
    overwrite=True,
)

print(f"generate lap mission finished")

# generate social agent routes

impatient_car = TrafficActor(
    name="patient_car",
    speed=Distribution(sigma=0.2, mean=0.5),
    lane_changing_model=LaneChangingModel(impatience=1, cooperative=0.25),
Пример #16
0
from pathlib import Path
from typing import Any, Tuple

import smarts.sstudio.types as types
from smarts.sstudio import gen_missions, gen_traffic

scenario = str(Path(__file__).parent)

patient_car = types.TrafficActor(name="car", )

shared_route = types.Route(
    begin=("edge-east", 0, 20),
    end=("edge-west", 0, 0),
)

traffic = types.Traffic(
    flows=[types.Flow(
        route=shared_route,
        rate=1,
        actors={patient_car: 1},
    )])

gen_missions(
    scenario,
    missions=[
        types.Mission(shared_route),
    ],
)
gen_traffic(scenario, traffic, "traffic")
Пример #17
0
def generate_left_turn_missions(
    missions,
    shuffle_missions,
    route_distributions,
    route_lanes,
    speed,
    map_dir,
    level_name,
    save_dir,
    stopwatcher_behavior,
    stopwatcher_route,
    seed,
    stops,
    bubbles,
    intersection_name,
    traffic_density,
):
    # dont worry about these seeds, theyre used by sumo
    sumo_seed = random.choice([0, 1, 2, 3, 4])
    stopwatcher_info = None
    stopwatcher_added = False
    if stopwatcher_behavior:
        stopwatcher_info = {
            "behavior": stopwatcher_behavior,
            "direction": get_direction(stopwatcher_route),
        }

    random.seed(seed)
    np.random.seed(seed)
    all_flows = []
    metadata = {"routes": {}, "total_vehicles": 0, "stopwatcher": None}

    scenario = save_dir + f"-flow-{seed}"

    # Remove old traffic route if it exists(otherwise, won't update to new flows)
    if os.path.exists(f"{scenario}/traffic/all.rou.xml"):
        shutil.rmtree(scenario)

    for route_key, route_info in route_distributions["routes"].items():
        # to skip None
        if route_info:
            ego_routes = [
                ego_mission_config_to_route(
                    ego_mission_config=ego_mission_config,
                    route_lanes=route_lanes,
                    stopwatcher_behavior=stopwatcher_behavior,
                )
                for ego_mission_config in missions
            ]
            # Not all routes need to have a custom start/end offset
            if "pos_offsets" in route_info:
                pos_offsets = route_info["pos_offsets"]
            else:
                pos_offsets = None
            flows, vehicles_log_info = generate_social_vehicles(
                route_distribution=route_info["distribution"],
                begin_time_init=route_info["begin_time_init"],
                num_vehicles=route_info["vehicles"],
                route_direction=get_direction(route_key),
                route_lanes=route_lanes,
                route_has_turn=route_info["has_turn"],
                start_end_on_different_lanes_probability=route_info[
                    "start_end_on_different_lanes_probability"
                ],
                stops=stops,
                deadlock_optimization=route_info["deadlock_optimization"],
                pos_offsets=pos_offsets,
                stopwatcher_info=stopwatcher_info,
                traffic_params={"speed": speed, "traffic_density": traffic_density},
            )
            if (
                stopwatcher_behavior
                and len(flows) > 0
                and get_direction(route_key) == stopwatcher_info["direction"]
            ):
                stopwatcher_added = True
                print(
                    f'stop watcher added to {get_direction(route_key)} flows among {route_info["vehicles"]} vehicles!'
                )
            all_flows.extend(flows)
            metadata["routes"][route_key] = vehicles_log_info
    scenario = save_dir + f"-flow-{seed}"
    if stopwatcher_behavior:
        if not stopwatcher_added and level_name != "no-traffic":
            print(
                f'There was no matching flows for stopwatcher, adding it to {stopwatcher_info["direction"]}.'
            )
            # vehicles_log_info[f'stopwatcher_{stopwatcher_info["behavior"]}']["count"] += 1
            all_flows.append(
                generate_stopwatcher(
                    stopwatcher_behavior=stopwatcher_info["behavior"],
                    stopwatcher_route=stopwatcher_info["direction"],
                    start_lane_id=0,
                    end_lane_id=0,
                )
            )
        scenario += f"-stopwatcher-{stopwatcher_info['behavior']}"

    copy_map_files(scenario, map_dir, speed)

    vehicles_to_not_hijack = []
    traffic = Traffic(flows=all_flows)
    try:
        gen_traffic(scenario, traffic, name=f"all", seed=sumo_seed)
        if stops:
            add_stops_to_traffic(scenario, stops, vehicles_to_not_hijack)
    except Exception as exception:
        print(exception)

    # Patch: Remove route files from traffic folder to make intersection empty.
    if traffic_density == "no-traffic":
        os.remove(f"{scenario}/traffic/all.rou.xml")

    if stopwatcher_behavior or "ego_hijacking_params" not in route_distributions:
        mission_objects = [Mission(ego_route) for ego_route in ego_routes]
    else:
        speed_m_per_s = float("".join(filter(str.isdigit, speed))) * 5.0 / 18.0
        hijacking_params = route_distributions["ego_hijacking_params"]
        zone_range = hijacking_params["zone_range"]
        waiting_time = hijacking_params["wait_to_hijack_limit_s"]
        start_time = (
            hijacking_params["start_time"]
            if hijacking_params["start_time"] != "default"
            else random.randint((LANE_LENGTH // speed_m_per_s), 60)
        )
        mission_objects = [
            Mission(
                ego_route,
                # Optional: control hijacking time, place, and emission.
                start_time=start_time,  # When to start hijacking (might start later).
                entry_tactic=TrapEntryTactic(
                    wait_to_hijack_limit_s=waiting_time,  # When to give up hijacking.
                    zone=MapZone(
                        start=(
                            ego_route.begin[0],
                            0,
                            ego_route.begin[2] + zone_range[0],
                        ),
                        length=zone_range[1],
                        n_lanes=(ego_route.begin[1] + 1),
                    ),  # Area to hijack.
                    exclusion_prefixes=vehicles_to_not_hijack,  # Don't hijack these.
                ),
            )
            for ego_route in ego_routes
        ]
    # Shuffle the missions so agents don't do the same route all the time.
    if shuffle_missions:
        random.shuffle(mission_objects)
    gen_missions(scenario, mission_objects)

    if bubbles:
        bubble_objects = [
            bubble_config_to_bubble_object(
                scenario, bubble_config, vehicles_to_not_hijack
            )
            for bubble_config in bubbles
        ]
        gen_bubbles(scenario, bubble_objects)

    if stopwatcher_behavior:
        metadata["stopwatcher"] = {
            "direction": stopwatcher_info["direction"],
            "behavior": stopwatcher_info["behavior"],
        }
    metadata["intersection"] = {
        "type": intersection_name[-1],
        "name": intersection_name,
    }
    metadata["total_vehicles"] = len(all_flows)
    metadata["seed"] = seed
    metadata["flow_id"] = f"flow_{seed}"
    with open(f"{scenario}/metadata.json", "w") as log:
        json.dump(metadata, log)
Пример #18
0
    Traffic,
    Flow,
    Route,
    RandomRoute,
    TrafficActor,
    Mission,
)

scenario = os.path.dirname(os.path.realpath(__file__))

gen_missions(
    scenario,
    [
        Mission(
            Route(begin=("edge-west-WE", 0, 10),
                  end=("edge-south-NS", 0, 40))),
        Mission(
            Route(begin=("edge-west-WE", 1, 10),
                  end=("edge-south-NS", 0, 40))),
    ],
)

gen_traffic(
    scenario,
    Traffic(flows=[
        Flow(
            route=RandomRoute(),
            rate=3600,
            actors={TrafficActor(name="car"): 1.0},
        )
    ]),