def climb(time, state, climb_V_cas, mach_climb, delta_ISA, vehicle): aircraft = vehicle['aircraft'] distance = state[0] altitude = state[1] mass = state[2] _, _, _, _, _, rho_ISA, _ = atmosphere_ISA_deviation(altitude, delta_ISA) throttle_position = 1.0 if climb_V_cas > 0: mach = V_cas_to_mach(climb_V_cas, altitude, delta_ISA) else: mach = mach_climb thrust_force, fuel_flow = turbofan( altitude, mach, throttle_position) # force [N], fuel flow [kg/hr] thrust_to_weight = aircraft['number_of_engines'] * thrust_force / (mass * GRAVITY) rate_of_climb, V_tas, climb_path_angle = rate_of_climb_calculation( thrust_to_weight, altitude, delta_ISA, mach, mass, vehicle) if rate_of_climb < 300: print('rate of climb violated!') x_dot = (V_tas * 101.269) * np.cos(climb_path_angle) # ft/min h_dot = rate_of_climb # ft/min W_dot = -2 * fuel_flow * 0.01667 # kg/min time_dot = h_dot dout = np.array([x_dot, h_dot, W_dot]) dout = dout.reshape(3, ) return dout
def climb(time, state, climb_V_cas, mach_climb, delta_ISA, vehicle): aircraft = vehicle['aircraft'] distance = state[0] altitude = state[1] mass = state[2] _, _, _, _, _, rho_ISA, _ = atmosphere_ISA_deviation(altitude, delta_ISA) throttle_position = 0.3 if climb_V_cas > 0: mach = V_cas_to_mach(climb_V_cas, altitude, delta_ISA) else: mach = mach_climb thrust_force, fuel_flow = turbofan( altitude, mach, throttle_position) # force [N], fuel flow [kg/hr] total_thrust_force = thrust_force * aircraft['number_of_engines'] total_fuel_flow = fuel_flow * aircraft['number_of_engines'] step_throttle = 0.1 while (total_fuel_flow < 0 and throttle_position <= 1): thrust_force, fuel_flow = turbofan( altitude, mach, throttle_position) # force [N], fuel flow [kg/hr] TSFC = (fuel_flow * GRAVITY) / thrust_force total_fuel_flow = aircraft['number_of_engines'] * fuel_flow throttle_position = throttle_position + step_throttle thrust_to_weight = aircraft['number_of_engines'] * thrust_force / (mass * GRAVITY) rate_of_climb, V_tas, climb_path_angle = rate_of_climb_calculation( thrust_to_weight, altitude, delta_ISA, mach, mass, vehicle) x_dot = (V_tas * 101.269) * np.cos(climb_path_angle) # ft/min h_dot = rate_of_climb # ft/min W_dot = -2 * fuel_flow * 0.01667 # kg/min # time_dot = h_dot dout = np.array([x_dot, h_dot, W_dot]) dout = dout.reshape(3, ) return dout
def mission(origin_destination_distance): global GRAVITY GRAVITY = 9.80665 gallon_to_liter = 3.7852 feet_to_nautical_miles = 0.000164579 tolerance = 100 airport_departure = vehicle['airport_departure'] airport_destination = vehicle['airport_destination'] # [kg] max_zero_fuel_weight = aircraft['maximum_zero_fuel_weight'] / GRAVITY # [kg] max_fuel_capacity = aircraft['maximum_fuel_capacity'] / GRAVITY operational_empty_weight = aircraft['operational_empty_weight'] / GRAVITY passenger_capacity_initial = aircraft['passenger_capacity'] engines_number = aircraft['number_of_engines'] max_engine_thrust = engine['maximum_thrust'] reference_load_factor = 0.85 heading = 2 # Operations and certification parameters: buffet_margin = 1.3 # [g] residual_rate_of_climb = 300 # [ft/min] ceiling = 40000 # [ft] UPDATE INPUT!!!!!!!!! descent_altitude = 1500 # Network and mission parameters fuel_density = 0.81 # [kg/l] fuel_price_per_kg = 1.0 # [per kg] fuel_price = (fuel_price_per_kg / fuel_density) * gallon_to_liter time_between_overhaul = 2500 # [hr] taxi_fuel_flow_reference = 5 # [kg/min] contingency_fuel_pct = 0.1 # pct ?????????????????? min_cruise_time = 3 # [min] go_around_allowance = 300 # Initial flight speed schedule climb_V_cas = 280 mach_climb = 0.78 cruise_V_cas = 310 descent_V_cas = 310 mach_descent = 0.78 delta_ISA = 0 captain_salary, first_officer_salary, flight_attendant_salary = crew_salary( 1000) regulated_takeoff_mass = regulated_takeoff_weight(vehicle) regulated_landing_mass = regulated_landing_weight(vehicle) max_takeoff_mass = regulated_takeoff_mass max_landing_mass = regulated_landing_mass takeoff_allowance_mass = 200 * max_takeoff_mass / 22000 approach_allowance_mass = 100 * max_takeoff_mass / 22000 average_taxi_in_time = 5 average_taxi_out_time = 10 payload = round(passenger_capacity_initial * operations['passenger_mass'] * reference_load_factor) initial_altitude = airport_departure['elevation'] f = 0 while f == 0: step = 500 out = 0 while out == 0: # Maximum altitude calculation max_altitude, rate_of_climb = maximum_altitude( vehicle, initial_altitude, ceiling, max_takeoff_mass, climb_V_cas, mach_climb, delta_ISA) # Optimal altitude calculation optim_altitude, rate_of_climb, _ = optimum_altitude( vehicle, initial_altitude, ceiling, max_takeoff_mass, climb_V_cas, mach_climb, delta_ISA) # Maximum altitude with minimum cruise time check g_climb = 4 / 1000 g_descent = 3 / 1000 K1 = g_climb + g_descent # Minimum distance at cruise stage Dmin = 10 * operations['mach_cruise'] * min_cruise_time K2 = (origin_destination_distance - Dmin + g_climb * (airport_departure['elevation'] + 1500) + g_descent * (airport_destination['elevation'] + 1500)) max_altitude_check = K2 / K1 if max_altitude_check > ceiling: max_altitude_check = ceiling if max_altitude > max_altitude_check: max_altitude = max_altitude_check if optim_altitude < max_altitude: final_altitude = optim_altitude else: final_altitude = max_altitude 'TODO: this should be replaced for information from ADS-B' # Check for next lower feasible RVSN FK check according to # present heading final_altitude = 1000 * (math.floor(final_altitude / 1000)) flight_level = final_altitude / 100 odd_flight_level = [ 90, 110, 130, 150, 170, 190, 210, 230, 250, 270, 290, 310, 330, 350, 370, 390, 410, 430, 450, 470, 490, 510 ] even_flight_level = [ 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300, 320, 340, 360, 380, 400, 420, 440, 460, 480, 500, 520 ] if (heading > 0 and heading <= 180): flight_level = min(odd_flight_level, key=lambda x: abs(x - flight_level)) final_altitude = flight_level * 100 elif (heading > 180 and heading <= 360): flight_level = min(even_flight_level, key=lambda x: abs(x - flight_level)) final_altitude = flight_level * 100 # Initial climb fuel estimation initial_altitude = initial_altitude + 1500 _, _, total_burned_fuel0, _ = climb_integration( max_takeoff_mass, mach_climb, climb_V_cas, delta_ISA, final_altitude, initial_altitude, vehicle) # Calculate best cruise mach mass_at_top_of_climb = max_takeoff_mass - total_burned_fuel0 operations['mach_cruise'] = maximum_range_mach( mass_at_top_of_climb, final_altitude, delta_ISA, vehicle) mach_climb = operations['mach_cruise'] mach_descent = operations['mach_cruise'] # Recalculate climb with new mach final_distance, total_climb_time, total_burned_fuel, final_altitude = climb_integration( max_takeoff_mass, mach_climb, climb_V_cas, delta_ISA, final_altitude, initial_altitude, vehicle) delta = total_burned_fuel0 - total_burned_fuel if delta < tolerance: out = 1 mass_at_top_of_climb = max_takeoff_mass - total_burned_fuel initial_cruise_altitude = final_altitude distance_climb = final_distance * feet_to_nautical_miles distance_cruise = origin_destination_distance - distance_climb altitude = initial_cruise_altitude flag = 1 while flag == 1: transition_altitude = crossover_altitude(operations['mach_cruise'], cruise_V_cas, delta_ISA) _, _, _, _, _, rho_ISA, _ = atmosphere_ISA_deviation( initial_cruise_altitude, delta_ISA) if altitude <= 10000: mach = V_cas_to_mach(250, altitude, delta_ISA) if (altitude > 10000 and altitude <= transition_altitude): mach = V_cas_to_mach(cruise_V_cas, altitude, delta_ISA) if altitude > transition_altitude: mach = operations['mach_cruise'] # Breguet calculation type for cruise performance total_cruise_time, final_cruise_mass = cruise_performance( altitude, delta_ISA, mach, mass_at_top_of_climb, distance_cruise, vehicle) final_cruise_altitude = altitude # Type of descent: 1 = full calculation | 2 = no descent computed type_of_descent = 1 if type_of_descent == 1: # Recalculate climb with new mach final_distance, total_descent_time, total_burned_fuel, final_altitude = descent_integration( final_cruise_mass, mach_descent, descent_V_cas, delta_ISA, descent_altitude, final_cruise_altitude, vehicle) distance_descent = final_distance * feet_to_nautical_miles distance_mission = distance_climb + distance_cruise + distance_descent distance_error = np.abs(origin_destination_distance - distance_mission) if distance_error <= 1.0: flag = 0 else: distance_cruise = distance_cruise - distance_error if type_of_descent == 2: flag = 0 total_burned_fuel = 0 final_distance = 0 total_decent_time = 0 total_burned_fuel = 0 final_altitude = 0 final_mission_mass = final_cruise_mass - total_burned_fuel total_mission_burned_fuel = max_takeoff_mass - final_mission_mass total_mission_flight_time = total_climb_time + \ total_cruise_time + total_descent_time total_mission_distance = distance_mission # Rule of three to estimate fuel flow during taxi taxi_fuel_flow = taxi_fuel_flow_reference * max_takeoff_mass / 22000 taxi_in_fuel = average_taxi_in_time * taxi_fuel_flow takeoff_fuel = total_mission_burned_fuel + takeoff_allowance_mass + taxi_in_fuel taxi_out_fuel = average_taxi_out_time * taxi_fuel_flow total_fuel_on_board = takeoff_fuel + taxi_out_fuel remaining_fuel = takeoff_fuel - total_mission_burned_fuel - \ approach_allowance_mass - taxi_in_fuel # Payload range envelope check MTOW_ZFW = max_zero_fuel_weight + total_fuel_on_board MTOW_LW = max_landing_mass + total_mission_burned_fuel delta_1 = max_takeoff_mass - MTOW_ZFW delta_2 = total_fuel_on_board - max_fuel_capacity delta_3 = max_takeoff_mass - MTOW_LW extra = (max_takeoff_mass - operational_empty_weight - payload) - takeoff_fuel[0] delta = max([delta_1, delta_2, delta_3, extra]) if delta > tolerance: max_takeoff_mass = max_takeoff_mass - delta else: # Payload reduction if restricted max_takeoff_mass = min([max_takeoff_mass, MTOW_ZFW, MTOW_LW]) payload_calculation = max_takeoff_mass - \ takeoff_fuel - operational_empty_weight if payload_calculation > payload: payload = payload else: payload = payload_calculation f = 1 passenger_capacity = np.round(payload / operations['passenger_mass']) load_factor = passenger_capacity / passenger_capacity_initial * 100 # DOC calculation fuel_mass = total_mission_burned_fuel + \ (average_taxi_out_time + average_taxi_in_time)*taxi_fuel_flow DOC = direct_operational_cost( time_between_overhaul, total_mission_flight_time, fuel_mass, operational_empty_weight, total_mission_distance, max_engine_thrust, engines_number, 0.35 * operational_empty_weight, max_takeoff_mass) return (DOC)
def optimum_altitude(initial_altitude, limit_altitude, mass, climb_V_cas, mach_climb, delta_ISA): transition_altitude = crossover_altitude(mach_climb, climb_V_cas, delta_ISA) altitude_step = 100 residual_rate_of_climb = 300 time = 0 distance = 0 fuel = 0 rate_of_climb = 9999 # Climb to 10000 ft with 250KCAS initial_altitude = initial_altitude + 1500 # 1500 [ft] altitude = initial_altitude final_altitude = 10000 throttle_position = 0.95 optimum_specific_rate = 0 while (rate_of_climb > residual_rate_of_climb and altitude < final_altitude): V_cas = 250 mach = V_cas_to_mach(V_cas, altitude, delta_ISA) thrust_force, fuel_flow = turbofan( altitude, mach, throttle_position) # force [N], fuel flow [kg/hr] thrust_to_weight = aircraft['number_of_engines'] * thrust_force / ( mass * GRAVITY) rate_of_climb, V_tas = rate_of_climb_calculation( thrust_to_weight, altitude, delta_ISA, mach, mass, aircraft_data) delta_time = altitude_step / rate_of_climb time = time + delta_time distance = distance + (V_tas / 60) * delta_time delta_fuel = (fuel_flow / 60) * delta_time fuel = fuel + delta_fuel mass = mass - delta_fuel altitude = altitude + altitude_step specific_rate = V_tas / fuel_flow if specific_rate > optimum_specific_rate: optimum_specific_rate = specific_rate optimum_altitude = altitude # Climb to transition altitude at constat CAS delta_altitude = 0 initial_altitude = 10000 + delta_altitude altitude = initial_altitude final_altitude = transition_altitude while (rate_of_climb > residual_rate_of_climb and altitude <= final_altitude): mach = V_cas_to_mach(V_cas, altitude, delta_ISA) thrust_force, fuel_flow = turbofan(altitude, mach, throttle_position) thrust_to_weight = aircraft['number_of_engines'] * thrust_force / ( mass * GRAVITY) rate_of_climb, V_tas = rate_of_climb_calculation( thrust_to_weight, altitude, delta_ISA, mach, mass, aircraft_data) delta_time = altitude_step / rate_of_climb time = time + delta_time distance = distance + (V_tas / 60) * delta_time delta_fuel = (fuel_flow / 60) * delta_time fuel = fuel + delta_fuel mass = mass - delta_fuel altitude = altitude + altitude_step specific_rate = V_tas / fuel_flow if specific_rate > optimum_specific_rate: optimum_specific_rate = specific_rate optimum_altitude = altitude # Climb to transition altitude at constant mach final_altitude = limit_altitude mach = mach_climb buffet_altitude_limit = buffet_altitude(mass, altitude, limit_altitude, mach_climb) while (rate_of_climb > residual_rate_of_climb and altitude <= final_altitude): V_cas = mach_to_V_cas(mach, altitude, delta_ISA) thrust_force, fuel_flow = turbofan(altitude, mach, throttle_position) thrust_to_weight = aircraft['number_of_engines'] * thrust_force / ( mass * GRAVITY) rate_of_climb, V_tas = rate_of_climb_calculation( thrust_to_weight, altitude, delta_ISA, mach, mass, aircraft_data) delta_time = altitude_step / rate_of_climb time = time + delta_time distance = distance + (V_tas / 60) * delta_time delta_fuel = (fuel_flow / 60) * delta_time fuel = fuel + delta_fuel mass = mass - delta_fuel altitude = altitude + altitude_step specific_rate = V_tas / fuel_flow if specific_rate > optimum_specific_rate: optimum_specific_rate = specific_rate optimum_altitude = altitude final_altitude = altitude - altitude_step if buffet_altitude_limit < final_altitude: final_altitude = buffet_altitude_limit optimum_altitude = final_altitude return optimum_altitude, rate_of_climb, optimum_specific_rate
def maximum_altitude(vehicle, initial_altitude, limit_altitude, mass, climb_V_cas, mach_climb, delta_ISA): aircraft = vehicle['aircraft'] transition_altitude = crossover_altitude(mach_climb, climb_V_cas, delta_ISA) altitude_step = 100 residual_rate_of_climb = 300 time = 0 distance = 0 fuel = 0 rate_of_climb = 9999 # Climb to 10000 ft with 250KCAS initial_altitude = initial_altitude + 1500 # 1500 [ft] altitude = initial_altitude final_altitude = 10000 throttle_position = 0.95 while (rate_of_climb > residual_rate_of_climb and altitude < final_altitude): # print(rate_of_climb) # print(altitude) V_cas = 250 mach = V_cas_to_mach(V_cas, altitude, delta_ISA) thrust_force, fuel_flow = turbofan( altitude, mach, throttle_position) # force [N], fuel flow [kg/hr] thrust_to_weight = aircraft['number_of_engines'] * thrust_force / ( mass * GRAVITY) rate_of_climb, V_tas, _ = rate_of_climb_calculation( thrust_to_weight, altitude, delta_ISA, mach, mass, vehicle) delta_time = altitude_step / rate_of_climb time = time + delta_time distance = distance + (V_tas / 60) * delta_time delta_fuel = (fuel_flow / 60) * delta_time fuel = fuel + delta_fuel mass = mass - delta_fuel altitude = altitude + altitude_step # Climb to transition altitude at constat CAS delta_altitude = 0 initial_altitude = 10000 + delta_altitude altitude = initial_altitude final_altitude = transition_altitude while (rate_of_climb > residual_rate_of_climb and altitude <= final_altitude): # print(rate_of_climb) # print(altitude) mach = V_cas_to_mach(V_cas, altitude, delta_ISA) thrust_force, fuel_flow = turbofan(altitude, mach, throttle_position) thrust_to_weight = aircraft['number_of_engines'] * thrust_force / ( mass * GRAVITY) rate_of_climb, V_tas, _ = rate_of_climb_calculation( thrust_to_weight, altitude, delta_ISA, mach, mass, vehicle) delta_time = altitude_step / rate_of_climb time = time + delta_time distance = distance + (V_tas / 60) * delta_time delta_fuel = (fuel_flow / 60) * delta_time fuel = fuel + delta_fuel mass = mass - delta_fuel altitude = altitude + altitude_step # Climb to transition altitude at constant mach final_altitude = limit_altitude mach = mach_climb buffet_altitude_limit = buffet_altitude(vehicle, mass, altitude, limit_altitude, mach_climb) while (rate_of_climb > residual_rate_of_climb and altitude <= final_altitude): # print(rate_of_climb) # print(altitude) V_cas = mach_to_V_cas(mach, altitude, delta_ISA) thrust_force, fuel_flow = turbofan(altitude, mach, throttle_position) thrust_to_weight = aircraft['number_of_engines'] * thrust_force / ( mass * GRAVITY) rate_of_climb, V_tas, _ = rate_of_climb_calculation( thrust_to_weight, altitude, delta_ISA, mach, mass, vehicle) delta_time = altitude_step / rate_of_climb time = time + delta_time distance = distance + (V_tas / 60) * delta_time delta_fuel = (fuel_flow / 60) * delta_time fuel = fuel + delta_fuel mass = mass - delta_fuel altitude = altitude + altitude_step final_altitude = altitude - altitude_step if buffet_altitude_limit < final_altitude: final_altitude = buffet_altitude_limit return final_altitude, rate_of_climb