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"]
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_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"]) ])
def test_output_format(mock_get): """ Check request output is formatted correctly. """ output = pd.DataFrame.from_dict( { "TEST1": { "aircraft_type": type, "current_flight_level": altitude, "ground_speed": speed, "latitude": latitude, "longitude": longitude, "vertical_speed": vertical_speed, "requested_flight_level": None, "cleared_flight_level": None }, }, orient="index", ) output.sim_t = 0 pos_all = all_positions() assert pos_all.equals(output) pos_id = aircraft_position("TEST1") assert pos_id.equals(output)
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_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_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
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_all_positions(): 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 pos = all_positions() 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) 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 = all_positions() assert isinstance(pos, pd.DataFrame) assert len(pos.index) == 2 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 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 # check that dataframe has sim_t attribute assert isinstance(pos.sim_t, float)
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)) if time.time()-t > 3: print("Sending synchronous commands...") t = time.time() for i in range(300, 400, 10): change_altitude(aircraft_id = aircraft_id, flight_level = i) print('Time to run 10 synchronous commands: {}'.format(time.time()-t)) print("Sending asynchronous commands...") t = time.time() commands = [] for i in range(400, 300, -10): commands.append(async_change_altitude(aircraft_id = aircraft_id, flight_level = i)) response = batch(commands)