Skip to content

Instantly share code, notes, and snippets.

@futureshocked
Created June 1, 2024 02:48
Show Gist options
  • Save futureshocked/cd757815f83ac08b2a2a288394d48150 to your computer and use it in GitHub Desktop.
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
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