Created
June 1, 2024 02:48
-
-
Save futureshocked/cd757815f83ac08b2a2a288394d48150 to your computer and use it in GitHub Desktop.
This program will detect these events during circuits at YSCN: take-off, landing, touch-and-go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pandas as pd | |
import matplotlib.pyplot as plt | |
import matplotlib.dates as mdates | |
import sys | |
def analyze_flight_data(file_path): | |
# Load the GPS data | |
gps_data = pd.read_csv(file_path) | |
gps_data['datetime'] = pd.to_datetime(gps_data['datetime']) | |
# Define criteria for touch-and-go, full-stop landing, and take-off | |
touch_and_go_speed_threshold = 60 | |
low_speed_threshold = 45 | |
full_stop_threshold = 30 | |
full_stop_intervals = 30 # seconds | |
# Define airport elevation | |
airport_elevation_m = 57 | |
# Calculate the rolling minimum speed over a 10-second window | |
window_size = 10 # seconds | |
gps_data['rolling_min_speed'] = gps_data['speed (kn)'].rolling(window=window_size, min_periods=1).min() | |
# Identify touch-and-go and full-stop landing points | |
events = [] | |
for i in range(window_size, len(gps_data) - window_size): | |
if gps_data['speed (kn)'][i] < touch_and_go_speed_threshold and gps_data['speed (kn)'][i - 1] >= touch_and_go_speed_threshold: | |
idx = gps_data[gps_data['datetime'] == gps_data['datetime'][i]].index[0] | |
if gps_data['rolling_min_speed'][i - window_size:i + window_size].iloc[-1] < gps_data['speed (kn)'][i]: | |
if gps_data['speed (kn)'][idx:idx + full_stop_intervals].min() < full_stop_threshold: | |
events.append((gps_data['datetime'][i], "Full-Stop Landing", "black")) | |
else: | |
events.append((gps_data['datetime'][i], "Touch-and-Go", "red")) | |
# Identify initial take-off as the first intersection of speed with the low-speed threshold (45 knots) | |
initial_take_off_time = None | |
for i in range(1, len(gps_data)): | |
if gps_data['speed (kn)'][i] >= low_speed_threshold and gps_data['speed (kn)'][i - 1] < low_speed_threshold: | |
initial_take_off_time = gps_data['datetime'][i] | |
break | |
# Add the initial take-off event | |
if initial_take_off_time: | |
events.append((initial_take_off_time, "Initial Take-Off", "yellow")) | |
# Sort the list by timestamps | |
events.sort() | |
# Format timestamps as HH:MM:SS | |
formatted_timestamps = [ | |
(timestamp.strftime("%H:%M:%S"), event, color) | |
for timestamp, event, color in events | |
] | |
# Plot the speed and altitude data with vertical lines and circle markings, and mark the initial take-off | |
fig, ax1 = plt.subplots(figsize=(12, 6)) | |
# Plot speed | |
ax1.set_xlabel('Time') | |
ax1.set_ylabel('Speed (knots)', color='tab:blue') | |
ax1.plot(gps_data['datetime'], gps_data['speed (kn)'], label='Speed (kn)', color='tab:blue') | |
ax1.axhline(y=touch_and_go_speed_threshold, color='r', linestyle='--', label='Touch-and-go speed threshold (60 knots)') | |
ax1.axhline(y=low_speed_threshold, color='orange', linestyle='--', label='Low speed threshold (45 knots)') | |
ax1.tick_params(axis='y', labelcolor='tab:blue') | |
# Add event circles | |
for timestamp, event, color in events: | |
ax1.plot(timestamp, gps_data[gps_data['datetime'] == timestamp]['speed (kn)'].values[0], 'o', color=color) | |
# Create a second y-axis for altitude | |
ax2 = ax1.twinx() | |
ax2.set_ylabel('Altitude (m)', color='tab:green') | |
ax2.plot(gps_data['datetime'], gps_data['alt (m)'], label='Altitude (m)', color='tab:green') | |
ax2.axhline(y=airport_elevation_m, color='purple', linestyle='--', label='Airport elevation') | |
ax2.tick_params(axis='y', labelcolor='tab:green') | |
# Set x-axis major ticks to 5-minute intervals | |
ax1.xaxis.set_major_locator(mdates.MinuteLocator(interval=5)) | |
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S')) | |
# Rotate x-axis labels for better readability | |
plt.setp(ax1.xaxis.get_majorticklabels(), rotation=45) | |
# Add text box with the list of events and their colors at the bottom left | |
events_text = "\n".join([f"{timestamp} - {event} ({color})" for timestamp, event, color in formatted_timestamps]) | |
plt.gcf().text(0.08, 0.3, events_text, fontsize=10, bbox=dict(facecolor='white', alpha=0.5)) | |
# Add legends | |
fig.tight_layout() | |
fig.legend(loc='upper left', bbox_to_anchor=(0.1, 0.9)) | |
plt.title('Speed and Altitude Over Time') | |
plt.grid(True) | |
plt.show() | |
return events | |
if __name__ == "__main__": | |
if len(sys.argv) != 2: | |
print("Usage: python script_name.py <input_csv_file>") | |
sys.exit(1) | |
file_path = sys.argv[1] | |
events = analyze_flight_data(file_path) | |
for timestamp, event in events: | |
print(f"{timestamp} - {event}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment