Converting historical data#

Apart from manually adding new aircraft to the simulation environment, AirTrafficSim can also automatically convert historical data to generate aircraft in the simulation environment. The ConvertHistoricDemo class in airtrafficsim_demo/environment/ConvertHistoricDemo.py provides a sample to set up such an environment.

Detecting procedures and entry points#

AirTrafficSim can detect the arrival and approach procedure of each flight base on historical data files. After detecting the procedures, AirTrafficSim will detect and store the entry position, time, speed, heading, and altitude of each aircraft base on a user-defined rule such as distance to a location.

airtrafficsim_data/environment/ConvertHistoricDemo.py#
23# Location of the historic data
24self.historic_data_path = Path(__file__).parent.parent.resolve().joinpath('data/flight_data/2018-05-01/')
25
26print("Analyzing flight data")
27# Set up arrival and approach data
28arrivals_dict, arrival_waypoints_coord_dict = get_arrival_data("VHHH", "07R")
29approach_dict, approach_waypoints_coord_dict = get_approach_data("VHHH", "07R")
30
31# Storage for historic aircraft data
32self.call_sign = []
33self.type = []
34self.star = []
35self.approach = []
36self.position = []
37self.speed = []
38self.start_alt = []
39self.heading = []
40self.time = []
41self.aircraft_list = {}
42
43# Loop all historic data files
44for file in self.historic_data_path.iterdir():
45        self.call_sign.append(file.name.removesuffix('.csv'))
46        
47        # Read and simplify flight trajectory
48        df = pd.read_csv(file)
49        traj = df[['lat', 'long']].to_numpy()
50        simplified = np.array(rdp(traj, 0.005))   
51
52        self.type.append(df['Aircraft_model'].iloc[0])
53
54        # Detect arrival and approach procedures
55        arrival_result, arrival_trajectory  = detect_sid_star(simplified, arrivals_dict, arrival_waypoints_coord_dict)
56        self.star.append(arrival_result)
57        approach_result, approach_trajectory = detect_sid_star(simplified, approach_dict, approach_waypoints_coord_dict)
58        self.approach.append(approach_result)
59
60        # Determine aircraft appearance point (150km to hong kong)
61        index = np.where(Cal.cal_great_circle_dist(traj[:, 0], traj[:, 1], 22.3193, 114.1694) < 200)[0][0]
62        self.position.append(traj[index])
63        self.speed.append(df['gspeed'].iloc[index])
64        self.start_alt.append(df['alt'].iloc[index])
65        self.heading.append(df['hangle'].iloc[index])
66        self.time.append(df['timestamp'].iloc[index])
67
68        print(file.name.removesuffix('.csv'), arrival_result, approach_result)
69
70print("Finished analyzing data")
71
72# Get starting time
73self.time = np.array(self.time)

Adding and deleting aircraft#

After converting historical flight data, AirTrafficSim will add aircraft at each timestep based on the stored entry time information. The aircraft will also be deleted if the aircraft has completed its flight plan and there is no next waypoint.

airtrafficsim_data/environment/ConvertHistoricDemo.py#
85def atc_command(self):
86    # Handle creation and deletion of aircraft
87    time = self.start_time + timedelta(seconds=self.global_time)
88    time = int(time.timestamp())
89    index = np.where(self.time == time)[0]
90    # Add aircraft
91    for i in index:
92        self.aircraft_list[self.call_sign[i]] = Aircraft(self.traffic, call_sign=self.call_sign[i], aircraft_type=self.type[i], flight_phase=FlightPhase.CRUISE, configuration=Config.CLEAN,
93                                                            lat=self.position[i][0], long=self.position[i][1], alt=self.start_alt[i], heading=self.heading[i], cas=self.speed[i], fuel_weight=10000.0, payload_weight=12000.0,
94                                                            arrival_airport="VHHH", arrival_runway="07R", star = self.star[i], approach = self.approach[i], cruise_alt=37000)
95    # Delete aircraft
96    index = self.traffic.index[self.traffic.ap.hv_next_wp == False]
97    for i in index:
98        self.traffic.del_aircraft(i)

Holding and vectoring#

A demo program is written to demonstrate commanding aircraft to vectoring and holding.

ConvertHistoricDemo.py#
94# User algorithm
95# Holding and vectoring
96if "5J150" in self.aircraft_list:
97    # self.aircraft_list["5J150"].set_vectoring(60, 195, "GUAVA")
98    if self.global_time == 1600:
99        self.aircraft_list["5J150"].set_holding(2, "BETTY", "VH")