Esempio n. 1
0
def test_boids(smarts, scenarios, bubble):
    # TODO: this is a hack to specify a seed to make this test pass
    seed(int(os.getenv("PYTHONHASHSEED", 42)))

    scenario = next(scenarios)
    smarts.reset(scenario)

    index = smarts.vehicle_index
    geometry = bubble_geometry(bubble, smarts.road_network)

    triggered_multiple_vehicles_in_bubble = False
    triggered_multiple_vehicles_airlocked = False

    # vehicle: steps per zone
    steps_driven_in_zones = defaultdict(lambda: ZoneSteps())
    # TODO: It's possible that multiple vehicles get spawned within the 500 steps but
    #       not all of them make it through the bubble completely causing the test to
    #       fail.
    for _ in range(500):
        smarts.step({})

        hijacked_actor_ids = []
        shadowed_actor_ids = []

        for vehicle in index.vehicles:
            position = Point(vehicle.position)
            in_bubble = position.within(geometry.bubble)
            is_shadowing = index.shadow_actor_id_from_vehicle_id(
                vehicle.id) is not None
            is_agent_controlled = vehicle.id in index.agent_vehicle_ids

            zone_steps = steps_driven_in_zones[vehicle.id]
            if position.within(geometry.bubble):
                zone_steps.in_bubble += 1
                hijacked_actor_ids.append(
                    index.actor_id_from_vehicle_id(vehicle.id))
                assert in_bubble and not is_shadowing and is_agent_controlled
            elif position.within(geometry.airlock_entry):
                zone_steps.airlock_entry += 1
                shadowed_actor_ids.append(
                    index.shadow_actor_id_from_vehicle_id(vehicle.id))
                assert not in_bubble and is_shadowing and not is_agent_controlled
            elif position.within(geometry.airlock_exit):
                zone_steps.airlock_exit += 1
                # TODO: Presently not implemented, but `is_shadowing` should be True
                assert not in_bubble and not is_shadowing and is_agent_controlled
            else:
                zone_steps.outside_bubble += 1
                assert not in_bubble and not is_shadowing and not is_agent_controlled

        if len(hijacked_actor_ids) > 1:
            triggered_multiple_vehicles_in_bubble = True

        if len(shadowed_actor_ids) > 1:
            triggered_multiple_vehicles_airlocked = True

        assert (len(set(hijacked_actor_ids)) <=
                1), "Boid vehicles must be controlled by the same actor"
        assert (len(set(shadowed_actor_ids)) <=
                1), "Boid vehicles must be shadowed by the same actor"

    # Just to have some padding, we want to be in each region at least 5 steps
    min_steps = 5
    for vehicle_id, zone in steps_driven_in_zones.items():
        assert all([
            zone.in_bubble > min_steps,
            zone.outside_bubble > min_steps,
            zone.airlock_entry > min_steps,
            zone.airlock_exit > min_steps,
        ]), (f"vehicle_id={vehicle_id}, zone={zone} doesn't meet "
             f"min_steps={min_steps} requirement")

    assert (triggered_multiple_vehicles_in_bubble
            ), "Multiple vehicles did not enter the bubble simultaneously"
    assert (triggered_multiple_vehicles_airlocked
            ), "Multiple vehicles were not airlocked simultaneously"
Esempio n. 2
0
def test_bubble_hijacking(smarts, scenarios, bubbles, num_vehicles):
    """Ensures bubble airlocking, hijacking, and relinquishing are functional.
    Additionally, we test with multiple bubbles and vehicles to ensure operation is
    correct in these conditions as well.
    """
    scenario = next(scenarios)
    smarts.reset(scenario)

    index = smarts.vehicle_index
    geometries = [bubble_geometry(b, smarts.road_network) for b in bubbles]

    # bubble: vehicle: steps per zone
    steps_driven_in_zones = {
        b.id: defaultdict(lambda: ZoneSteps())
        for b in bubbles
    }
    vehicles_made_to_through_bubble = {b.id: [] for b in bubbles}
    for _ in range(300):
        smarts.step({})
        for vehicle in index.vehicles:
            for bubble, geometry in zip(bubbles, geometries):
                position = Point(vehicle.position)
                in_bubble = position.within(geometry.bubble)
                is_shadowing = (index.shadow_actor_id_from_vehicle_id(
                    vehicle.id) is not None)
                is_agent_controlled = vehicle.id in index.agent_vehicle_ids()

                zone_steps = steps_driven_in_zones[bubble.id][vehicle.id]
                if position.within(geometry.bubble):
                    zone_steps.in_bubble += 1
                    assert in_bubble and not is_shadowing and is_agent_controlled
                elif position.within(geometry.airlock_entry):
                    zone_steps.airlock_entry += 1
                    assert not in_bubble and is_shadowing and not is_agent_controlled
                elif position.within(geometry.airlock_exit):
                    zone_steps.airlock_exit += 1
                    # TODO: Presently not implemented, but `is_shadowing` should be True
                    assert not in_bubble and not is_shadowing and is_agent_controlled
                    if vehicle.id not in vehicles_made_to_through_bubble[
                            bubble.id]:
                        vehicles_made_to_through_bubble[bubble.id].append(
                            vehicle.id)
                elif not any(
                    [position.within(geom.airlock) for geom in geometries]):
                    # Not in any bubble; airlock is the encompassing region
                    zone_steps.outside_bubble += 1
                    assert (not in_bubble and not is_shadowing
                            and not is_agent_controlled)

    # Just to have some padding, we want to be in each region at least 5 steps
    min_steps = 5
    for bubble_id, zones in steps_driven_in_zones.items():
        vehicle_ids = vehicles_made_to_through_bubble[bubble_id]
        assert (len(vehicle_ids) >=
                num_vehicles), "Insufficient no. vehicles drove through bubble"
        for vehicle_id in vehicle_ids[:num_vehicles]:
            zone = zones[vehicle_id]
            assert all([
                zone.in_bubble > min_steps,
                zone.outside_bubble > min_steps,
                zone.airlock_entry > min_steps,
                zone.airlock_exit > min_steps,
            ]), (
                f"bubble={bubble_id}, vehicle_id={vehicle_id}, zone={zone} doesn't meet "
                f"min_steps={min_steps} requirement")