示例#1
0
def test_wrong_id():
    """
    Expect a row in a dataframe with NAN if requested aircraft not in simulation.
    """
    cmd = reset_simulation()
    assert cmd == True

    pos = aircraft_position(aircraft_id)
    # print(pos)
    assert pos.loc[aircraft_id].isnull().all()

    cmd = create_aircraft(
        aircraft_id=aircraft_id,
        type=type,
        latitude=latitude,
        longitude=longitude,
        heading=heading,
        flight_level=flight_level,
        speed=speed,
    )
    assert cmd == True

    pos = aircraft_position([aircraft_id, aircraft_id_2])
    assert len(pos.index) == 2
    assert pos.loc[aircraft_id_2].isnull().all()
示例#2
0
def test_route_waypoints(upload_test_sector_scenario):
    """
    Test list_route(), direct_to_waypoint()
    """

    cmd = reset_simulation()
    assert cmd == True

    upload_test_sector_scenario()

    # Get the position
    position = all_positions()
    acid1, acid2 = position.index

    route1 = list_route(acid1)
    route2 = list_route(acid2)

    assert route1["aircraft_id"] == acid1
    assert route2["aircraft_id"] == acid2

    assert route1["next_waypoint"] == 'FIYRE'
    assert route1["route_name"] == 'ASCENSION'
    assert len(route1["route_waypoints"]) == 5

    assert route2["next_waypoint"] == 'SPIRT'
    assert route2["route_name"] == 'FALLEN'
    assert len(route2["route_waypoints"]) == 5

    route2["route_waypoints"].reverse()
    assert all([
        wp1 == wp2 for wp1, wp2 in zip(route1["route_waypoints"],
                                       route2["route_waypoints"])
    ])
示例#3
0
def test_change_heading(upload_test_sector_scenario):

    cmd = reset_simulation()
    assert cmd == True

    upload_test_sector_scenario()

    # Get the position
    position = all_positions()
    acid1, acid2 = position.index

    # Test with an invalid heading.
    invalid_heading = 400
    with pytest.raises(AssertionError):
        change_heading(aircraft_id=acid1, heading=invalid_heading)

    # Give the command to change heading.
    # Aircraft is originally headed north (0 degrees)
    new_heading = 90
    cmd = change_heading(aircraft_id=acid1, heading=new_heading)
    assert cmd == True

    # Check that the heading has changed.
    resp = simulation_step()
    assert resp == True

    new_position = all_positions()
    assert new_position.loc[acid1, "longitude"] > position.loc[acid1,
                                                               "longitude"]
示例#4
0
def test_no_positions():
    """
    Expect empty dataframe when no aircraft exist.
    """
    cmd = reset_simulation()
    assert cmd == True

    pos_df = all_positions()
    assert pos_df.empty
def test_output_create_aircraft():

    # reset so that no aircraft exist
    reset_simulation()

    output = create_aircraft(aircraft_id, type, latitude, longitude, heading,
                             speed, altitude, flight_level)
    assert output == True

    with pytest.raises(HTTPError):
        create_aircraft(
            aircraft_id,
            type,
            latitude,
            longitude,
            heading,
            speed,
            altitude,
            flight_level,
        )
示例#6
0
def test_aircraft_position():
    cmd = reset_simulation()
    assert cmd == True

    cmd = create_aircraft(
        aircraft_id=aircraft_id,
        type=type,
        latitude=latitude,
        longitude=longitude,
        heading=heading,
        flight_level=flight_level,
        speed=speed,
    )
    assert cmd == True

    cmd = create_aircraft(
        aircraft_id=aircraft_id_2,
        type=type_2,
        latitude=latitude_2,
        longitude=longitude_2,
        heading=heading_2,
        flight_level=flight_level_2,
        speed=speed_2,
    )
    assert cmd == True

    pos = aircraft_position(aircraft_id)
    assert isinstance(pos, pd.DataFrame)
    assert len(pos.index) == 1
    assert pos.loc[aircraft_id]["aircraft_type"] == type
    assert pos.loc[aircraft_id]["latitude"] == pytest.approx(0, abs=1e-5)
    assert pos.loc[aircraft_id]["longitude"] == pytest.approx(0, abs=1e-5)
    assert pos.loc[aircraft_id]["vertical_speed"] == 0
    # flight level is returned in feet
    assert pos.loc[aircraft_id]["current_flight_level"] == flight_level * 100
    assert pos.loc[aircraft_id]["ground_speed"] == 0

    # check that dataframe has sim_t attribute
    assert isinstance(pos.sim_t, float)

    pos = aircraft_position([aircraft_id, aircraft_id_2])
    assert len(pos.index) == 2
    assert pos.loc[aircraft_id_2]["aircraft_type"] == type_2
    assert pos.loc[aircraft_id_2]["latitude"] == pytest.approx(0, abs=1e-5)
    assert pos.loc[aircraft_id_2]["longitude"] == pytest.approx(0, abs=1e-5)
    assert pos.loc[aircraft_id_2]["vertical_speed"] == 0
    # flight level is returned in feet
    assert pos.loc[aircraft_id_2]["current_flight_level"] == flight_level_2 * 100
    assert pos.loc[aircraft_id_2]["ground_speed"] == 0
def test_upload_sector(rootdir):
    """
    Create scenario on the simulator host and load.
    Check two aircraft created succesfully with associated route.
    """
    test_sector = "dodo-test-sector"

    test_file = os.path.join(rootdir, test_sector)

    resp = reset_simulation()
    assert resp == True

    resp = upload_sector(filename="{}.geojson".format(test_file),
                         sector_name=test_sector)
    assert resp == True
def test_async_request(upload_test_sector_scenario):
    """
    Tests async_request() function
    """

    cmd = reset_simulation()
    assert cmd == True

    upload_test_sector_scenario()

    # Get the position
    position = all_positions()
    acid1, acid2 = position.index

    commands = []
    commands.append(async_change_altitude(aircraft_id=acid1, flight_level=100))
    commands.append(async_change_heading(aircraft_id=acid1, heading=90))

    results = batch(commands)

    assert results == True

    resp = simulation_step()
    assert resp == True

    new_position = all_positions()
    assert new_position.loc[acid1, "current_flight_level"] < position.loc[
        acid1, "current_flight_level"]
    assert new_position.loc[acid1, "longitude"] > position.loc[acid1,
                                                               "longitude"]

    # send more commands - return to original values
    more_commands = []
    more_commands.append(
        async_change_altitude(aircraft_id=acid1, flight_level=400))
    more_commands.append(async_change_speed(aircraft_id=acid1, speed=100))

    results = batch(more_commands)

    assert results == True

    # send an invalid and a valid command
    commands_wrong = []
    commands_wrong.append(async_change_heading(aircraft_id=acid1, heading=0))
    commands_wrong.append(async_change_speed(aircraft_id=acid1, speed=-5))

    with pytest.raises(Exception):
        results = batch(commands_wrong)
def test_wrong_id():
    """
    Test separation functions when one of provided IDs does not exist in simulation.
    """
    cmd = reset_simulation()
    assert cmd == True

    separation0 = euclidean_separation(from_aircraft_id=aircraft_id)
    assert isinstance(separation0, pd.DataFrame)
    assert np.isnan(separation0.loc[aircraft_id, aircraft_id])

    cmd = create_aircraft(
        aircraft_id=aircraft_id,
        type=type,
        latitude=latitude,
        longitude=longitude,
        heading=heading,
        flight_level=flight_level,
        speed=speed,
    )
    assert cmd == True

    separation1 = geodesic_separation(
        from_aircraft_id=[aircraft_id, aircraft_id_2],
        to_aircraft_id=[aircraft_id, aircraft_id_2],
    )
    assert isinstance(separation1, pd.DataFrame)
    assert np.isnan(separation1.loc[aircraft_id, aircraft_id_2])

    separation2 = great_circle_separation(
        from_aircraft_id=[aircraft_id, aircraft_id_2],
        to_aircraft_id=aircraft_id)
    assert isinstance(separation2, pd.DataFrame)
    assert np.isnan(separation2.loc[aircraft_id_2, aircraft_id])

    separation3 = vertical_separation(
        from_aircraft_id=aircraft_id,
        to_aircraft_id=[aircraft_id, aircraft_id_2])
    assert isinstance(separation3, pd.DataFrame)
    assert np.isnan(separation3.loc[aircraft_id, aircraft_id_2])

    separation4 = euclidean_separation(from_aircraft_id=aircraft_id,
                                       to_aircraft_id=aircraft_id_2)
    assert isinstance(separation4, pd.DataFrame)
    assert np.isnan(separation4.loc[aircraft_id, aircraft_id_2])
def test_flight_level(upload_test_sector_scenario):

    cmd = reset_simulation()
    assert cmd == True

    upload_test_sector_scenario()

    # Get the position
    position = all_positions()
    acid1, acid2 = position.index

    assert cleared_flight_level(acid1) == 400
    assert requested_flight_level(acid1) == 400

    # In BlueSky overflier aircraft is inialised below requested flight level
    assert 39995 < current_flight_level(acid1) <= 40000

    assert cleared_flight_level(acid2) == 200
    assert requested_flight_level(acid2) == 400
    assert current_flight_level(acid2) == 20000
示例#11
0
def test_loss_of_separation():
    """
    Tests loss_of_separation returns correct separation score.
    """
    cmd = reset_simulation()
    assert cmd == True

    cmd = create_aircraft(
        aircraft_id=aircraft_id,
        type=type,
        latitude=latitude,
        longitude=longitude,
        heading=heading,
        flight_level=flight_level,
        speed=speed,
    )
    assert cmd == True

    cmd = create_aircraft(
        aircraft_id=aircraft_id_2,
        type=type_2,
        latitude=latitude_2,
        longitude=longitude_2,
        heading=heading_2,
        flight_level=flight_level_2,
        speed=speed_2,
    )
    assert cmd == True

    score1 = loss_of_separation(aircraft_id, aircraft_id_2)
    assert score1 == 0

    score2 = loss_of_separation(aircraft_id, aircraft_id)
    assert score2 == -1

    score3 = loss_of_separation(aircraft_id_2, aircraft_id_2)
    assert score3 == -1

    new_aircraft_id = "TST3003"
    score4 = loss_of_separation(aircraft_id, new_aircraft_id)
    assert np.isnan(score4)
示例#12
0
def test_change_speed():
    cmd = reset_simulation()
    assert cmd == True

    aircraft_id = "TST1001"
    type = "B744"
    latitude = 0
    longitude = 0
    heading = 0
    flight_level = 250
    speed = 265

    cmd = create_aircraft(
        aircraft_id=aircraft_id,
        type=type,
        latitude=latitude,
        longitude=longitude,
        heading=heading,
        flight_level=flight_level,
        speed=speed,
    )
    assert cmd == True

    # Check the altitude.
    position = aircraft_position(aircraft_id)

    # In the returned data frame aircraft_id is uppercase.
    aircraft_id = aircraft_id.upper()
    # Aircaft initial speed differs from specified speed.
    assert position.loc[aircraft_id]["ground_speed"] > 200

    # Test with an invalid speed.
    invalid_speed = -1
    with pytest.raises(AssertionError):
        change_speed(aircraft_id=aircraft_id, speed=invalid_speed)

    # Give the command to change speed.
    new_speed = 400
    cmd = change_speed(aircraft_id=aircraft_id, speed=new_speed)
    assert cmd == True
def test_change_altitude(upload_test_sector_scenario):

    cmd = reset_simulation()
    assert cmd == True

    upload_test_sector_scenario()

    # Get the position
    position = all_positions()
    acid1, acid2 = position.index

    # Give the command to descend.
    new_flight_level = 100
    cmd = change_altitude(aircraft_id=acid1, flight_level=new_flight_level)
    assert cmd == True

    # Check that the new altitude is below the original one.
    resp = simulation_step()
    assert resp == True

    new_position = all_positions()
    assert new_position.loc[acid1, "current_flight_level"] < position.loc[
        acid1, "current_flight_level"]
def test_upload_scenario(rootdir):
    """
    Runs through a basic scenario covering all the main functionality
    (no aircraft commands are sent).
    """

    resp = reset_simulation()
    assert resp == True

    # 1. SIMULATION SHOULD BE EMPTY

    info0 = simulation_info()
    assert info0["scenario_name"] is None
    assert len(info0["aircraft_ids"]) == 0

    # 2. LOAD SECTOR AND SCENARIO

    test_scenario_file = os.path.join(rootdir, "dodo-test-scenario")
    test_sector_file = os.path.join(rootdir, "dodo-test-sector")

    resp = upload_sector(filename=f"{test_sector_file}.geojson",
                         sector_name="test_sector")
    assert resp == True

    resp = upload_scenario(filename=f"{test_scenario_file}.json",
                           scenario_name="test_scenario")
    assert resp == True

    # 3. CHECK SIMULATION HAS AIRCRAFT WITH POSITIONS AND ROUTES

    info = simulation_info()
    assert info["scenario_name"] == "test_scenario"
    assert len(info["aircraft_ids"]) == 2

    pos = all_positions()
    assert isinstance(pos, pd.DataFrame)
    assert len(pos.index) == 2

    acid1, acid2 = pos.index

    route1 = list_route(acid1)
    route2 = list_route(acid2)

    assert isinstance(route1, dict)
    assert isinstance(route2, dict)
    assert len(route1["route_waypoints"]) == 5
    assert len(route2["route_waypoints"]) == 5

    # 4. STEP FORWARD THE SIMULATION & CHECK IT ADVANCED (5 x 1 second scenario time)
    for i in range(5):
        info1 = simulation_info()
        resp = simulation_step()
        assert resp == True

    info2 = simulation_info()

    assert info2["scenario_time"] - info1["scenario_time"] == pytest.approx(
        1.0)

    # EXPECT CHANGE IN AIRCRAFT LATITUDES
    # aircraft 1 is travelling from latitude ~51 to ~53
    # aircraft 2 is heading in the opposite direction

    pos1 = all_positions()
    assert pos.loc[acid1, "longitude"] == pos1.loc[acid1, "longitude"]
    assert pos.loc[acid1, "latitude"] < pos1.loc[acid1, "latitude"]

    assert pos.loc[acid2, "longitude"] == pos1.loc[acid2, "longitude"]
    assert pos.loc[acid2, "latitude"] > pos1.loc[acid2, "latitude"]

    # 5. CHANGE STEP SIZE & TAKE STEP
    # SIMULATION SHOULD MOVE FOWARD BY MORE THAN BEFORE (10 second scenario time)
    resp = set_simulation_rate_multiplier(10)
    assert resp == True

    resp = simulation_step()
    assert resp == True

    info3 = simulation_info()
    assert info3["scenario_time"] - info2["scenario_time"] == pytest.approx(
        10.0)

    # CHANGE IN AIRCRAFT LATITUDE SHOULD BE MORE IN THIS SINGLE 10s STEP
    # COMPARED TO PREVIOUS 5 x 1 second STEPS
    pos2 = all_positions()
    assert (abs(pos2.loc[acid1, "latitude"] - pos1.loc[acid1, "latitude"]) >
            abs(pos1.loc[acid1, "latitude"] - pos.loc[acid1, "latitude"]))
    assert (abs(pos2.loc[acid2, "latitude"] - pos1.loc[acid2, "latitude"]) >
            abs(pos1.loc[acid2, "latitude"] - pos.loc[acid2, "latitude"]))
def test_separation(expected_great_circle):
    """
    Tests that all separation functions return a dataframe using a variety of inputs.
    """
    cmd = reset_simulation()
    assert cmd == True

    cmd = create_aircraft(
        aircraft_id=aircraft_id,
        type=type,
        latitude=latitude,
        longitude=longitude,
        heading=heading,
        flight_level=flight_level,
        speed=speed,
    )
    assert cmd == True

    cmd = create_aircraft(
        aircraft_id=aircraft_id_2,
        type=type_2,
        latitude=latitude_2,
        longitude=longitude_2,
        heading=heading_2,
        flight_level=flight_level_2,
        speed=speed_2,
    )
    assert cmd == True

    separation1 = geodesic_separation(
        from_aircraft_id=[aircraft_id, aircraft_id_2],
        to_aircraft_id=[aircraft_id, aircraft_id_2],
    )
    assert isinstance(separation1, pd.DataFrame)
    assert separation1.loc[aircraft_id, aircraft_id_2] == pytest.approx(
        1000 * 176.92, 0.01)

    separation2 = great_circle_separation(
        from_aircraft_id=[aircraft_id, aircraft_id_2],
        to_aircraft_id=aircraft_id)
    assert isinstance(separation2, pd.DataFrame)
    expected = expected_great_circle(latitude, longitude, latitude_2,
                                     longitude_2)
    assert separation2.loc[aircraft_id_2,
                           aircraft_id] == pytest.approx(expected, 0.01)

    separation3 = vertical_separation(
        from_aircraft_id=aircraft_id,
        to_aircraft_id=[aircraft_id, aircraft_id_2])
    assert isinstance(separation3, pd.DataFrame)
    ## altitude is provided as flight_level, which must be converted to:
    # feet (*100) and then to metres (*0.3048)
    assert (
        separation3.loc[aircraft_id,
                        aircraft_id_2] == abs(flight_level - flight_level_2) *
        100 * SCALE_FEET_TO_METRES)

    separation4 = euclidean_separation(from_aircraft_id=aircraft_id,
                                       to_aircraft_id=aircraft_id_2)
    assert isinstance(separation4, pd.DataFrame)

    ecef = pyproj.Proj(proj="geocent", ellps="WGS84", datum="WGS84")
    lla = pyproj.Proj(proj="latlong", ellps="WGS84", datum="WGS84")

    from_ECEF = pyproj.transform(lla, ecef, longitude, latitude,
                                 flight_level * 100 * SCALE_FEET_TO_METRES)
    to_ECEF = pyproj.transform(lla, ecef, longitude_2, latitude_2,
                               flight_level_2 * 100 * SCALE_FEET_TO_METRES)

    assert separation4.loc[aircraft_id, aircraft_id_2] == pytest.approx(
        euclidean(from_ECEF, to_ECEF), 0.01)

    separation5 = euclidean_separation(from_aircraft_id=aircraft_id_2)
    assert isinstance(separation5, pd.DataFrame)
    assert separation5.loc[aircraft_id_2, aircraft_id_2] == 0
示例#16
0
from pydodo import (change_altitude, change_heading, change_speed,
                    aircraft_position, all_positions,
                    reset_simulation, create_aircraft,
                    async_change_altitude, batch)
import time

reset_simulation()

aircraft_id = "TST1001"
type = "B744"
latitude = 0
longitude = 0
heading = 0
flight_level = 250
speed = 200

cmd = create_aircraft(aircraft_id = aircraft_id,
                      type = type,
                      latitude = latitude,
                      longitude = longitude,
                      heading = heading,
                      flight_level = flight_level,
                      speed = speed)


t = time.time()
print('Waiting...')
while True:
    pos = all_positions()
    # print(format_runtime(time.time()-start))
def test_bluesky_response():
    """Test that bluesky is running and responding before any other tests are run"""
    resp = reset_simulation()
    assert resp == True